diff --git a/struct.go b/struct.go index d8b175a..3ba1922 100644 --- a/struct.go +++ b/struct.go @@ -71,6 +71,7 @@ type CustomTypescript interface { } func (s *Struct) RenderCustom(opts *Options, w io.Writer) (err error) { + ww := newTabScanner(w, opts.indents[1]) ctit := reflect.TypeOf((*CustomTypescript)(nil)).Elem() var implementingType reflect.Type = nil if s.t.Implements(ctit) { @@ -84,12 +85,12 @@ func (s *Struct) RenderCustom(opts *Options, w io.Writer) (err error) { if !ok { return errors.New("couldn't get method RenderCustomTypescript") } - _, err = fmt.Fprintf(w, "\n") + _, err = fmt.Fprintf(ww, "\n") o := reflect.New(s.t) if implementingType.Kind() != reflect.Ptr { o = o.Elem() } - wv := reflect.ValueOf(w) + wv := reflect.ValueOf(ww) r := m.Func.Call([]reflect.Value{o, wv}) if len(r) > 0 && !r[0].IsNil() { switch r0t := r[0].Interface().(type) { diff --git a/tabscanner.go b/tabscanner.go new file mode 100644 index 0000000..8affaea --- /dev/null +++ b/tabscanner.go @@ -0,0 +1,37 @@ +package struct2ts + +import "io" + +type tabScanner struct { + output io.Writer + tabs []byte +} + +func (ts *tabScanner) Write(bs []byte) (n int, err error) { + p := 0 + var rn int + for pos, b := range bs { + switch b { + case '\n': + rn, err = ts.output.Write(bs[p : pos+1]) + n += rn + if err != nil { + return + } + _, err = ts.output.Write(ts.tabs) + if err != nil { + return + } + p = pos + 1 + } + } + rn, err = ts.output.Write(bs[p:]) + return n + rn, err +} + +func newTabScanner(w io.Writer, tabs string) io.Writer { + return &tabScanner{ + output: w, + tabs: []byte(tabs), + } +} diff --git a/tabscanner_test.go b/tabscanner_test.go new file mode 100644 index 0000000..f838e7e --- /dev/null +++ b/tabscanner_test.go @@ -0,0 +1,95 @@ +package struct2ts + +import ( + "bytes" + "testing" +) + +func TestTabScanner_Write(t *testing.T) { + tests := []struct { + Name string + Input struct { + Tabs string + Buffers []string + } + Expected struct { + Output string + n *int + } + }{ + { + "One new line mid string - one input, 3 spaces", + struct { + Tabs string + Buffers []string + }{Tabs: " ", Buffers: []string{"Hello how are you?\nI'm fine thanks!"}}, + struct { + Output string + n *int + }{Output: "Hello how are you?\n I'm fine thanks!"}, + }, + { + "One new line end string - one input, 3 spaces", + struct { + Tabs string + Buffers []string + }{Tabs: " ", Buffers: []string{"Hello how are you?\n"}}, + struct { + Output string + n *int + }{Output: "Hello how are you?\n "}, + }, + { + "One new line start string - one input, 3 spaces", + struct { + Tabs string + Buffers []string + }{Tabs: " ", Buffers: []string{"\nHello how are you?"}}, + struct { + Output string + n *int + }{Output: "\n Hello how are you?"}, + }, + { + "empty string", + struct { + Tabs string + Buffers []string + }{Tabs: " ", Buffers: []string{""}}, + struct { + Output string + n *int + }{Output: ""}, + }, + { + "Just a new line", + struct { + Tabs string + Buffers []string + }{Tabs: " ", Buffers: []string{"\n"}}, + struct { + Output string + n *int + }{Output: "\n "}, + }, + } + for _, test := range tests { + t.Run(test.Name, func(t *testing.T) { + outputBuffer := bytes.NewBuffer(nil) + ts := newTabScanner(outputBuffer, test.Input.Tabs) + for _, s := range test.Input.Buffers { + _, err := ts.Write([]byte(s)) + if err != nil { + t.Error("Buffer write error", err) + } + } + if outputBuffer.String() != test.Expected.Output { + t.Log("Output buffer doesn't match. Got ") + t.Log(outputBuffer.String()) + t.Log("expected") + t.Log(test.Expected.Output) + t.Fail() + } + }) + } +}