mirror of
https://github.com/rwxrob/bonzai
synced 2024-11-04 18:00:18 +00:00
Factor out functional (fn), sets, loops
This commit is contained in:
parent
7e9b0cf872
commit
193727dc0f
6
cmd.go
6
cmd.go
@ -8,7 +8,7 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/rwxrob/bonzai/comp"
|
||||
"github.com/rwxrob/bonzai/filter"
|
||||
"github.com/rwxrob/bonzai/loop"
|
||||
)
|
||||
|
||||
// Cmd is a struct the easier to use and read when creating
|
||||
@ -79,10 +79,10 @@ func (x *Cmd) Run() {
|
||||
if cmd.Completer == nil {
|
||||
|
||||
list := comp.Standard(cmd, args...)
|
||||
filter.Println(list)
|
||||
loop.Println(list)
|
||||
Exit()
|
||||
}
|
||||
filter.Println(cmd.Completer(cmd, args...))
|
||||
loop.Println(cmd.Completer(cmd, args...))
|
||||
Exit()
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,8 @@ import (
|
||||
"github.com/rwxrob/bonzai"
|
||||
"github.com/rwxrob/bonzai/check"
|
||||
"github.com/rwxrob/bonzai/comp"
|
||||
"github.com/rwxrob/bonzai/filter"
|
||||
"github.com/rwxrob/bonzai/filt"
|
||||
"github.com/rwxrob/bonzai/maps"
|
||||
)
|
||||
|
||||
// Help provides help documentation for the caller allowing the specific
|
||||
@ -47,7 +48,7 @@ func helpCompleter(x comp.Command, args ...string) []string {
|
||||
if !check.IsNil(caller) {
|
||||
other := caller.GetOther()
|
||||
if other != nil {
|
||||
list = append(list, filter.Keys(other)...)
|
||||
list = append(list, maps.Keys(other)...)
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,5 +56,5 @@ func helpCompleter(x comp.Command, args ...string) []string {
|
||||
return list
|
||||
}
|
||||
|
||||
return filter.HasPrefix(list, args[0])
|
||||
return filt.HasPrefix(list, args[0])
|
||||
}
|
||||
|
21
comp/file.go
21
comp/file.go
@ -4,7 +4,10 @@
|
||||
package comp
|
||||
|
||||
import (
|
||||
"github.com/rwxrob/bonzai/filter"
|
||||
"strings"
|
||||
|
||||
"github.com/rwxrob/bonzai/filt"
|
||||
"github.com/rwxrob/bonzai/maps"
|
||||
"github.com/rwxrob/bonzai/util"
|
||||
)
|
||||
|
||||
@ -12,15 +15,23 @@ import (
|
||||
// passed. If nothing is passed assumes the current working directory.
|
||||
func File(x Command, args ...string) []string {
|
||||
match := ""
|
||||
dir := "."
|
||||
dir := ""
|
||||
|
||||
if len(args) > 0 {
|
||||
match = args[0]
|
||||
// FIXME if there is an unescaped "/" at all, truncate the directory
|
||||
// and keep the rest to add on later for match
|
||||
if strings.HasSuffix(args[0], "/") {
|
||||
dir = args[0]
|
||||
match = ""
|
||||
} else {
|
||||
match = args[0]
|
||||
}
|
||||
}
|
||||
|
||||
list := []string{}
|
||||
list = append(list, util.Files(dir)...)
|
||||
list = filter.HasPrefix(list, match)
|
||||
list = append(list, maps.Prefix(util.Files(dir), dir)...)
|
||||
list = filt.HasPrefix(list, match)
|
||||
list = maps.CleanPaths(list)
|
||||
return list
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,8 @@
|
||||
package comp
|
||||
|
||||
import (
|
||||
"github.com/rwxrob/bonzai/filter"
|
||||
"github.com/rwxrob/bonzai/filt"
|
||||
"github.com/rwxrob/bonzai/set"
|
||||
)
|
||||
|
||||
// Standard completion is resolved as follows:
|
||||
@ -36,11 +37,11 @@ func Standard(x Command, args ...string) []string {
|
||||
list := []string{}
|
||||
list = append(list, x.GetCommands()...)
|
||||
list = append(list, x.GetParams()...)
|
||||
list = filter.Minus(list, x.GetHidden())
|
||||
list = set.Minus(list, x.GetHidden())
|
||||
|
||||
if len(args) == 0 {
|
||||
return list
|
||||
}
|
||||
|
||||
return filter.HasPrefix(list, args[0])
|
||||
return filt.HasPrefix(list, args[0])
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
|
||||
"github.com/rwxrob/bonzai"
|
||||
"github.com/rwxrob/bonzai/comp"
|
||||
"github.com/rwxrob/bonzai/filter"
|
||||
"github.com/rwxrob/bonzai/filt"
|
||||
)
|
||||
|
||||
func ExampleStandard() {
|
||||
@ -39,7 +39,7 @@ func ExampleStandard() {
|
||||
if len(args) == 0 {
|
||||
return list
|
||||
}
|
||||
return filter.HasPrefix(list, args[0])
|
||||
return filt.HasPrefix(list, args[0])
|
||||
}
|
||||
fmt.Println(comp.Standard(foo, `t`))
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package filter
|
||||
package filt
|
||||
|
||||
import (
|
||||
"strings"
|
@ -1,19 +1,19 @@
|
||||
// Copyright 2022 Robert S. Muhlestein.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package filter_test
|
||||
package filt_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/rwxrob/bonzai/filter"
|
||||
"github.com/rwxrob/bonzai/filt"
|
||||
)
|
||||
|
||||
func ExampleHasPrefix() {
|
||||
set := []string{
|
||||
"one", "two", "three", "four", "five", "six", "seven",
|
||||
}
|
||||
fmt.Println(filter.HasPrefix(set, "t"))
|
||||
fmt.Println(filt.HasPrefix(set, "t"))
|
||||
// Output:
|
||||
// [two three]
|
||||
}
|
16
fn/fn.go
Normal file
16
fn/fn.go
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright 2022 Robert S. Muhlestein.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package fn
|
||||
|
||||
// Map executes an operator function provided on each item in the
|
||||
// slice returning a new slice. If error handling is needed it should be
|
||||
// handled within an enclosure within the function. This keeps
|
||||
// signatures simple and functional.
|
||||
func Map[I any, O any](slice []I, f func(in I) O) []O {
|
||||
list := []O{}
|
||||
for _, i := range slice {
|
||||
list = append(list, f(i))
|
||||
}
|
||||
return list
|
||||
}
|
65
fn/fn_test.go
Normal file
65
fn/fn_test.go
Normal file
@ -0,0 +1,65 @@
|
||||
// Copyright 2022 Robert S. Muhlestein.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package fn_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/rwxrob/bonzai/fn"
|
||||
)
|
||||
|
||||
func ExampleHasPrefix() {
|
||||
set := []string{
|
||||
"one", "two", "three", "four", "five", "six", "seven",
|
||||
}
|
||||
fmt.Println(fn.HasPrefix(set, "t"))
|
||||
// Output:
|
||||
// [two three]
|
||||
}
|
||||
|
||||
func ExamplePrintln() {
|
||||
set := []string{"doe", "ray", "mi"}
|
||||
filter.Println(set)
|
||||
bools := []bool{false, true, true}
|
||||
filter.Println(bools)
|
||||
// Output:
|
||||
// doe
|
||||
// ray
|
||||
// mi
|
||||
// false
|
||||
// true
|
||||
// true
|
||||
}
|
||||
|
||||
func ExampleKeys() {
|
||||
m1 := map[string]int{"two": 2, "three": 3, "one": 1}
|
||||
m2 := map[string]string{"two": "two", "three": "three", "one": "one"}
|
||||
fmt.Println(filter.Keys(m1))
|
||||
fmt.Println(filter.Keys(m2))
|
||||
// Output:
|
||||
// [one three two]
|
||||
// [one three two]
|
||||
}
|
||||
|
||||
func ExamplePrefix() {
|
||||
fmt.Println(filter.Prefix([]string{"foo", "bar"}, "my"))
|
||||
// Output:
|
||||
// [myfoo mybar]
|
||||
}
|
||||
|
||||
func ExampleCleanPaths() {
|
||||
paths := []string{
|
||||
``,
|
||||
`.`,
|
||||
`./`,
|
||||
`./thing`,
|
||||
`/sub/../../thing`,
|
||||
}
|
||||
filter.Println(filter.CleanPaths(paths))
|
||||
// Output:
|
||||
// .
|
||||
// .
|
||||
// .
|
||||
// /thing
|
||||
}
|
27
generic/generic.go
Normal file
27
generic/generic.go
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright 2022 Robert S. Muhlestein.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package generic
|
||||
|
||||
// Number combines the primitives generally considered numbers by JSON
|
||||
// and other high-level structure data representations.
|
||||
type Number interface {
|
||||
int | int64 | int32 | int16 | int8 |
|
||||
uint64 | uint32 | uint16 | uint8 |
|
||||
float64 | float32
|
||||
}
|
||||
|
||||
// Text combines byte slice and string.
|
||||
type Text interface {
|
||||
[]byte | string
|
||||
}
|
||||
|
||||
// Sharable are the types that have representations in JSON, YAML, TOML
|
||||
// and other high-level structured data representations.
|
||||
type Sharable interface {
|
||||
int | int64 | int32 | int16 | int8 |
|
||||
uint64 | uint32 | uint16 | uint8 |
|
||||
float64 | float32 |
|
||||
[]byte | string |
|
||||
bool
|
||||
}
|
22
loop/loop.go
Normal file
22
loop/loop.go
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
Package loop shamelessly attempts to bring the better parts of Lisp loops to Go specifically in order to enable rapid, and clean applications development --- particularly when replacing shell scripts with Go.
|
||||
*/
|
||||
package loop
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Do executes the given function for each item in the slice. If any
|
||||
// error is encountered processing stops and error returned.
|
||||
func Do[T any](set []T, p func(i T) error) error {
|
||||
for _, i := range set {
|
||||
if err := p(i); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Println prints ever element of the set.
|
||||
func Println[T any](set []T) {
|
||||
Do(set, func(i T) error { fmt.Println(i); return nil })
|
||||
}
|
17
loop/loop_test.go
Normal file
17
loop/loop_test.go
Normal file
@ -0,0 +1,17 @@
|
||||
package loop_test
|
||||
|
||||
import "github.com/rwxrob/bonzai/loop"
|
||||
|
||||
func ExamplePrintln() {
|
||||
set := []string{"doe", "ray", "mi"}
|
||||
loop.Println(set)
|
||||
bools := []bool{false, true, true}
|
||||
loop.Println(bools)
|
||||
// Output:
|
||||
// doe
|
||||
// ray
|
||||
// mi
|
||||
// false
|
||||
// true
|
||||
// true
|
||||
}
|
28
maps/maps.go
Normal file
28
maps/maps.go
Normal file
@ -0,0 +1,28 @@
|
||||
package maps
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"sort"
|
||||
|
||||
"github.com/rwxrob/bonzai/fn"
|
||||
)
|
||||
|
||||
// Prefix returns a new slice with prefix added to each string.
|
||||
func Prefix(in []string, pre string) []string {
|
||||
return fn.Map(in, func(i string) string { return pre + i })
|
||||
}
|
||||
|
||||
// Keys returns the keys in lexicographically sorted order.
|
||||
func Keys[T any](m map[string]T) []string {
|
||||
keys := []string{}
|
||||
for k, _ := range m {
|
||||
keys = append(keys, k)
|
||||
sort.Strings(keys)
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
// CleanPaths runs filepath.Clean on each item in the slice and returns.
|
||||
func CleanPaths(paths []string) []string {
|
||||
return fn.Map(paths, func(i string) string { return filepath.Clean(i) })
|
||||
}
|
39
maps/maps_test.go
Normal file
39
maps/maps_test.go
Normal file
@ -0,0 +1,39 @@
|
||||
package maps_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/rwxrob/bonzai/maps"
|
||||
)
|
||||
|
||||
func ExampleKeys() {
|
||||
m1 := map[string]int{"two": 2, "three": 3, "one": 1}
|
||||
m2 := map[string]string{"two": "two", "three": "three", "one": "one"}
|
||||
fmt.Println(maps.Keys(m1))
|
||||
fmt.Println(maps.Keys(m2))
|
||||
// Output:
|
||||
// [one three two]
|
||||
// [one three two]
|
||||
}
|
||||
|
||||
func ExamplePrefix() {
|
||||
fmt.Println(maps.Prefix([]string{"foo", "bar"}, "my"))
|
||||
// Output:
|
||||
// [myfoo mybar]
|
||||
}
|
||||
|
||||
func ExampleCleanPaths() {
|
||||
paths := []string{
|
||||
``,
|
||||
`.`,
|
||||
`./`,
|
||||
`./thing`,
|
||||
`/sub/../../thing`,
|
||||
}
|
||||
filter.Println(filter.CleanPaths(paths))
|
||||
// Output:
|
||||
// .
|
||||
// .
|
||||
// .
|
||||
// /thing
|
||||
}
|
24
set/set.go
Normal file
24
set/set.go
Normal file
@ -0,0 +1,24 @@
|
||||
package set
|
||||
|
||||
type Text interface {
|
||||
string | []byte
|
||||
}
|
||||
|
||||
// Minus performs a set "minus" operation by returning a new set with
|
||||
// the elements of the second set removed from it.
|
||||
func Minus[T Text, M Text](set []T, min []M) []T {
|
||||
m := []T{}
|
||||
for _, i := range set {
|
||||
var seen bool
|
||||
for _, n := range min {
|
||||
if string(n) == string(i) {
|
||||
seen = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !seen {
|
||||
m = append(m, i)
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
16
set/set_test.go
Normal file
16
set/set_test.go
Normal file
@ -0,0 +1,16 @@
|
||||
package set_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/rwxrob/bonzai/set"
|
||||
)
|
||||
|
||||
func ExampleMinus() {
|
||||
s := []string{
|
||||
"one", "two", "three", "four", "five", "six", "seven",
|
||||
}
|
||||
fmt.Println(set.Minus(s, []string{"two", "four", "six"}))
|
||||
// Output:
|
||||
// [one three five seven]
|
||||
}
|
@ -3,7 +3,7 @@ package util
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/rwxrob/bonzai/filter"
|
||||
"github.com/rwxrob/bonzai/filt"
|
||||
)
|
||||
|
||||
// Files returns a slice of strings matching the names of the files
|
||||
@ -26,5 +26,5 @@ func Files(dir string) []string {
|
||||
}
|
||||
|
||||
func FilesWith(dir, pre string) []string {
|
||||
return filter.HasPrefix(Files(dir), pre)
|
||||
return filt.HasPrefix(Files(dir), pre)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user