deno.land / x / esm@v135_2 / server / structs.go
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300package server
import ( "bytes" "container/list" "encoding/json" "fmt" "io" "os" "path" "sort" "strings" "sync")
type devFS struct { cwd string}
func (fs devFS) ReadFile(name string) ([]byte, error) { return os.ReadFile(path.Join(fs.cwd, name))}
func (fs devFS) Lstat(name string) (os.FileInfo, error) { return os.Lstat(path.Join(fs.cwd, name))}
type stringSet struct { lock sync.RWMutex set map[string]struct{}}
func newStringSet(keys ...string) *stringSet { set := make(map[string]struct{}, len(keys)) for _, key := range keys { set[key] = struct{}{} } return &stringSet{set: set}}
func (s *stringSet) Len() int { s.lock.RLock() defer s.lock.RUnlock()
return len(s.set)}
func (s *stringSet) Has(key string) bool { s.lock.RLock() defer s.lock.RUnlock()
_, ok := s.set[key] return ok}
func (s *stringSet) Add(key string) { s.lock.Lock() defer s.lock.Unlock()
s.set[key] = struct{}{}}
func (s *stringSet) Remove(key string) { s.lock.Lock() defer s.lock.Unlock()
delete(s.set, key)}
func (s *stringSet) Reset() { s.lock.Lock() defer s.lock.Unlock()
s.set = map[string]struct{}{}}
func (s *stringSet) Values() []string { s.lock.RLock() defer s.lock.RUnlock()
a := make([]string, len(s.set)) i := 0 for key := range s.set { a[i] = key i++ } return a}
func (s *stringSet) SortedValues() []string { values := sort.StringSlice(s.Values()) sort.Sort(values) return values}
type StringOrMap struct { Str string Map map[string]interface{}}
func (a *StringOrMap) UnmarshalJSON(b []byte) error { if err := json.Unmarshal(b, &a.Str); err != nil { return json.Unmarshal(b, &a.Map) } return nil}
func (a *StringOrMap) MainValue() string { if a.Str != "" { return a.Str } if a.Map != nil { v, ok := a.Map["."] if ok { s, isStr := v.(string) if isStr { return s } } } return ""}
type SortedPaths []string
func (a SortedPaths) Len() int { return len(a)}
func (a SortedPaths) Less(i, j int) bool { iParts := strings.Split(a[i], "/") jParts := strings.Split(a[j], "/") for k := 0; k < len(iParts) && k < len(jParts); k++ { if iParts[k] != jParts[k] { return iParts[k] < jParts[k] } } return len(iParts) < len(jParts)}
func (a SortedPaths) Swap(i, j int) { a[i], a[j] = a[j], a[i]}
// The orderedMap type, has similar operations as the default map type// copied from https://gitlab.com/c0b/go-ordered-jsontype orderedMap struct { lock sync.RWMutex m map[string]interface{} l *list.List keys map[string]*list.Element // the double linked list for delete and lookup to be O(1)}
// Create a new orderedMapfunc newOrderedMap() *orderedMap { return &orderedMap{ m: make(map[string]interface{}), l: list.New(), keys: make(map[string]*list.Element), }}
// Set sets value for particular key, this will remember the order of keys inserted// but if the key already exists, the order is not updated.func (om *orderedMap) Set(key string, value interface{}) { om.lock.Lock() defer om.lock.Unlock() if _, ok := om.m[key]; !ok { om.keys[key] = om.l.PushBack(key) } om.m[key] = value}
// Entry returns the key and value by the given list elementfunc (om *orderedMap) Entry(e *list.Element) (string, interface{}) { key := e.Value.(string) return key, om.m[key]}
// UnmarshalJSON implements type json.Unmarshaler interface, so can be called in json.Unmarshal(data, om)func (om *orderedMap) UnmarshalJSON(data []byte) error { dec := json.NewDecoder(bytes.NewReader(data)) dec.UseNumber()
// must open with a delim token '{' t, err := dec.Token() if err != nil { return err } if delim, ok := t.(json.Delim); !ok || delim != '{' { return fmt.Errorf("expect JSON object open with '{'") }
err = om.parseobject(dec) if err != nil { return err }
t, err = dec.Token() if err != io.EOF { return fmt.Errorf("expect end of JSON object but got more token: %T: %v or err: %v", t, t, err) }
return nil}
func (om *orderedMap) parseobject(dec *json.Decoder) (err error) { var t json.Token for dec.More() { t, err = dec.Token() if err != nil { return err }
key, ok := t.(string) if !ok { return fmt.Errorf("expecting JSON key should be always a string: %T: %v", t, t) }
t, err = dec.Token() if err == io.EOF { break } else if err != nil { return err }
var value interface{} value, err = handledelim(t, dec) if err != nil { return err }
// om.keys = append(om.keys, key) om.keys[key] = om.l.PushBack(key) om.m[key] = value }
t, err = dec.Token() if err != nil { return err } if delim, ok := t.(json.Delim); !ok || delim != '}' { return fmt.Errorf("expect JSON object close with '}'") }
return nil}
func parsearray(dec *json.Decoder) (arr []interface{}, err error) { var t json.Token arr = make([]interface{}, 0) for dec.More() { t, err = dec.Token() if err != nil { return }
var value interface{} value, err = handledelim(t, dec) if err != nil { return } arr = append(arr, value) } t, err = dec.Token() if err != nil { return } if delim, ok := t.(json.Delim); !ok || delim != ']' { err = fmt.Errorf("expect JSON array close with ']'") return }
return}
func handledelim(t json.Token, dec *json.Decoder) (res interface{}, err error) { if delim, ok := t.(json.Delim); ok { switch delim { case '{': om2 := newOrderedMap() err = om2.parseobject(dec) if err != nil { return } return om2, nil case '[': var value []interface{} value, err = parsearray(dec) if err != nil { return } return value, nil default: return nil, fmt.Errorf("unexpected delimiter: %q", delim) } } return t, nil}
Version Info