github.com/xhghs/rclone@v1.51.1-0.20200430155106-e186a28cced8/fs/config_list.go (about) 1 package fs 2 3 import ( 4 "bytes" 5 "encoding/csv" 6 "fmt" 7 ) 8 9 // CommaSepList is a comma separated config value 10 // It uses the encoding/csv rules for quoting and escaping 11 type CommaSepList []string 12 13 // SpaceSepList is a space separated config value 14 // It uses the encoding/csv rules for quoting and escaping 15 type SpaceSepList []string 16 17 type genericList []string 18 19 func (l CommaSepList) String() string { 20 return genericList(l).string(',') 21 } 22 23 // Set the List entries 24 func (l *CommaSepList) Set(s string) error { 25 return (*genericList)(l).set(',', []byte(s)) 26 } 27 28 // Type of the value 29 func (CommaSepList) Type() string { 30 return "CommaSepList" 31 } 32 33 // Scan implements the fmt.Scanner interface 34 func (l *CommaSepList) Scan(s fmt.ScanState, ch rune) error { 35 return (*genericList)(l).scan(',', s, ch) 36 } 37 38 func (l SpaceSepList) String() string { 39 return genericList(l).string(' ') 40 } 41 42 // Set the List entries 43 func (l *SpaceSepList) Set(s string) error { 44 return (*genericList)(l).set(' ', []byte(s)) 45 } 46 47 // Type of the value 48 func (SpaceSepList) Type() string { 49 return "SpaceSepList" 50 } 51 52 // Scan implements the fmt.Scanner interface 53 func (l *SpaceSepList) Scan(s fmt.ScanState, ch rune) error { 54 return (*genericList)(l).scan(' ', s, ch) 55 } 56 57 func (gl genericList) string(sep rune) string { 58 var buf bytes.Buffer 59 w := csv.NewWriter(&buf) 60 w.Comma = sep 61 err := w.Write(gl) 62 if err != nil { 63 // can only happen if w.Comma is invalid 64 panic(err) 65 } 66 w.Flush() 67 return string(bytes.TrimSpace(buf.Bytes())) 68 } 69 70 func (gl *genericList) set(sep rune, b []byte) error { 71 if len(b) == 0 { 72 *gl = nil 73 return nil 74 } 75 r := csv.NewReader(bytes.NewReader(b)) 76 r.Comma = sep 77 78 record, err := r.Read() 79 switch _err := err.(type) { 80 case nil: 81 *gl = record 82 case *csv.ParseError: 83 err = _err.Err // remove line numbers from the error message 84 } 85 return err 86 } 87 88 func (gl *genericList) scan(sep rune, s fmt.ScanState, ch rune) error { 89 token, err := s.Token(true, func(rune) bool { return true }) 90 if err != nil { 91 return err 92 } 93 return gl.set(sep, bytes.TrimSpace(token)) 94 }