refc: 重构了 nfctl
This commit is contained in:
81
nft/nfctl/pkg/loading/loading.go
Normal file
81
nft/nfctl/pkg/loading/loading.go
Normal file
@ -0,0 +1,81 @@
|
||||
package loading
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Type int
|
||||
|
||||
const (
|
||||
TypeProcessing Type = iota
|
||||
TypeInfo
|
||||
TypeSuccess
|
||||
TypeWarning
|
||||
TypeError
|
||||
)
|
||||
|
||||
func (t Type) Symbol() string {
|
||||
switch t {
|
||||
case TypeSuccess:
|
||||
return "✔️ "
|
||||
case TypeWarning:
|
||||
return "❗ "
|
||||
case TypeError:
|
||||
return "❌ "
|
||||
case TypeInfo:
|
||||
return "❕ "
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
type Loading struct {
|
||||
Content string
|
||||
Type Type
|
||||
}
|
||||
|
||||
func Print(ctx context.Context, ch <-chan *Loading) {
|
||||
var (
|
||||
ok bool
|
||||
frames = []string{"|", "/", "-", "\\"}
|
||||
start = time.Now()
|
||||
loading = &Loading{}
|
||||
)
|
||||
|
||||
for {
|
||||
for _, frame := range frames {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case loading, ok = <-ch:
|
||||
if !ok || loading == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if loading.Content == "" {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
continue
|
||||
}
|
||||
|
||||
switch loading.Type {
|
||||
case TypeInfo,
|
||||
TypeSuccess,
|
||||
TypeWarning,
|
||||
TypeError:
|
||||
// Clear the loading animation
|
||||
fmt.Printf("\r\033[K")
|
||||
fmt.Printf("%s%s\n", loading.Type.Symbol(), loading.Content)
|
||||
loading.Content = ""
|
||||
}
|
||||
default:
|
||||
elapsed := time.Since(start).Seconds()
|
||||
if loading.Content != "" {
|
||||
fmt.Printf("\r\033[K%s %s (%.2fs)", frame, loading.Content, elapsed)
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
27
nft/nfctl/pkg/loading/loading_test.go
Normal file
27
nft/nfctl/pkg/loading/loading_test.go
Normal file
@ -0,0 +1,27 @@
|
||||
package loading
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestLoadingPrint(t *testing.T) {
|
||||
ch := make(chan *Loading)
|
||||
|
||||
Print(context.TODO(), ch)
|
||||
ch <- &Loading{Content: "处理中(1)..."}
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
ch <- &Loading{Content: "处理完成(1)", Type: TypeSuccess}
|
||||
|
||||
ch <- &Loading{Content: "处理中(2)..."}
|
||||
|
||||
time.Sleep(4 * time.Second)
|
||||
|
||||
ch <- &Loading{Content: "处理失败(2)", Type: TypeError}
|
||||
|
||||
time.Sleep(2 * time.Second)
|
||||
close(ch)
|
||||
}
|
Reference in New Issue
Block a user