github.com/yandex/pandora@v0.5.32/core/datasource/std.go (about) 1 package datasource 2 3 import ( 4 "bytes" 5 "io" 6 "io/ioutil" 7 "strings" 8 9 "github.com/yandex/pandora/core" 10 "github.com/yandex/pandora/lib/ioutil2" 11 ) 12 13 func NewBuffer(buf *bytes.Buffer) core.DataSource { 14 return buffer{Buffer: buf} 15 } 16 17 type buffer struct { 18 *bytes.Buffer 19 ioutil2.NopCloser 20 } 21 22 func (b buffer) OpenSource() (wc io.ReadCloser, err error) { 23 return b, nil 24 } 25 26 // NewReader returns dummy core.DataSource that returns it on OpenSource call, wrapping it 27 // ioutil.NopCloser if r is not io.Closer. 28 // NOTE(skipor): such wrapping hides Seek and other methods that can be used. 29 func NewReader(r io.Reader) core.DataSource { 30 return &readerSource{r} 31 } 32 33 type readerSource struct { 34 source io.Reader 35 } 36 37 func (r *readerSource) OpenSource() (rc io.ReadCloser, err error) { 38 if rc, ok := r.source.(io.ReadCloser); ok { 39 return rc, nil 40 } 41 // Need to add io.Closer, but don't want to hide seeker. 42 rs, ok := r.source.(io.ReadSeeker) 43 if ok { 44 return &struct { 45 io.ReadSeeker 46 ioutil2.NopCloser 47 }{ReadSeeker: rs}, nil 48 } 49 return ioutil.NopCloser(r.source), nil 50 } 51 52 func NewString(s string) core.DataSource { 53 return &stringSource{Reader: strings.NewReader(s)} 54 } 55 56 type stringSource struct { 57 *strings.Reader 58 ioutil2.NopCloser 59 } 60 61 func (s stringSource) OpenSource() (rc io.ReadCloser, err error) { 62 return s, nil 63 } 64 65 type InlineConfig struct { 66 Data string `validate:"required"` 67 } 68 69 func NewInline(conf InlineConfig) core.DataSource { 70 return NewString(conf.Data) 71 } 72 73 // TODO(skipor): InMemory DataSource, that reads all nested source data in open to buffer.