diff --git a/README.md b/README.md index cbab4d0..f09954b 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ The struct tag schema schema used by fixedwidth is: `fixed:"{startPos},{endPos}, The `startPos` and `endPos` arguments control the position within a line. `startPos` and `endPos` must both be positive integers greater than 0. Positions start at 1. The interval is inclusive. -The `alignment` argument controls the alignment of the value within it's interval. The valid options are `default`[2](#f2), `right`, and `left`. The `alignment` is optional and can be omitted. +The `alignment` argument controls the alignment of the value within it's interval. The valid options are `default`[2](#f2), `right`, `left`, and `none`. The `alignment` is optional and can be omitted. The `padChar` argument controls the character that will be used to pad any empty characters in the interval after writing the value. The default padding character is a space. The `padChar` is optional and can be omitted. @@ -120,6 +120,7 @@ encoder.SetUseCodepointIndices(true) | `default` | Field is left aligned | The padding character is trimmed from both right and left of value | | `left` | Field is left aligned | The padding character is trimmed from right of value | | `right` | Field is right aligned | The padding character is trimmed from left of value | +| `none` | Field is left aligned | The padding character is not trimmed from value. Useful for nested structs. | ## Notes 1. `{}` indicates an argument. `[]` indicates and optional segment [^](#a1) diff --git a/decode.go b/decode.go index b43ba20..2780afd 100644 --- a/decode.go +++ b/decode.go @@ -207,6 +207,8 @@ func rawValueFromLine(value rawValue, startPos, endPos int, format format) rawVa trimFunc = func(r rawValue) rawValue { return r.trimLeft(string(format.padChar)) } + case alignmentNone: + trimFunc = func(r rawValue) rawValue { return r } default: trimFunc = func(r rawValue) rawValue { return r.trim(string(format.padChar)) diff --git a/decode_test.go b/decode_test.go index b5597cd..149c1d1 100644 --- a/decode_test.go +++ b/decode_test.go @@ -386,7 +386,7 @@ func TestDecodeSetUseCodepointIndices(t *testing.T) { } -func TestDecodeSetUseCodepointIndices_Nested(t *testing.T) { +func TestDecode_Nested(t *testing.T) { type Nested struct { First string `fixed:"1,3"` Second string `fixed:"4,6"` @@ -394,9 +394,9 @@ func TestDecodeSetUseCodepointIndices_Nested(t *testing.T) { type Test struct { First string `fixed:"1,3"` - Second Nested `fixed:"4,9"` + Second Nested `fixed:"4,9,none"` Third string `fixed:"10,12"` - Fourth Nested `fixed:"13,18"` + Fourth Nested `fixed:"13,18,none"` Fifth string `fixed:"19,21"` } @@ -416,6 +416,17 @@ func TestDecodeSetUseCodepointIndices_Nested(t *testing.T) { Fifth: "012", }, }, + { + name: "All ASCII characters with padding", + raw: []byte(" 2 B 5 E 8 H 1 \n"), + expected: Test{ + First: "2", + Second: Nested{First: "B", Second: "5"}, + Third: "E", + Fourth: Nested{First: "8", Second: "H"}, + Fifth: "1", + }, + }, { name: "Multi-byte characters", raw: []byte("123x☃x456x☃x789x☃x012\n"), @@ -427,63 +438,15 @@ func TestDecodeSetUseCodepointIndices_Nested(t *testing.T) { Fifth: "012", }, }, - } { - t.Run(tt.name, func(t *testing.T) { - d := NewDecoder(bytes.NewReader(tt.raw)) - d.SetUseCodepointIndices(true) - var s Test - err := d.Decode(&s) - if err != nil { - t.Errorf("Unexpected err: %v", err) - } - if !reflect.DeepEqual(tt.expected, s) { - t.Errorf("Decode(%v) want %v, have %v", tt.raw, tt.expected, s) - } - }) - } -} - -func TestDecodeSetUseCodepointIndices_PaddingTrimmed(t *testing.T) { - type Nested struct { - First int64 `fixed:"1,2,right,0"` - Second string `fixed:"3,4"` - Third string `fixed:"5,6"` - Fourth string `fixed:"7,8"` - } - type Test struct { - First Nested `fixed:"1,8"` - Second string `fixed:"9,10"` - } - - for _, tt := range []struct { - name string - raw []byte - expected Test - }{ - { - name: "All ASCII characters", - raw: []byte("00 11"), - expected: Test{ - First: Nested{ - First: 0, - Second: "", - Third: "", - Fourth: "", - }, - Second: "11", - }, - }, { - name: "Multi-byte characters", - raw: []byte("00 ☃☃"), + name: "Multi-byte characters with padding", + raw: []byte(" ☃ Ñ ☃ Ñ ☃ Ñ ☃ \n"), expected: Test{ - First: Nested{ - First: 0, - Second: "", - Third: "", - Fourth: "", - }, - Second: "☃☃", + First: "☃", + Second: Nested{First: "Ñ", Second: "☃"}, + Third: "Ñ", + Fourth: Nested{First: "☃", Second: "Ñ"}, + Fifth: "☃", }, }, } { diff --git a/format.go b/format.go index 9c83611..17cd524 100644 --- a/format.go +++ b/format.go @@ -2,6 +2,7 @@ package fixedwidth const ( defaultAlignment alignment = "default" + alignmentNone alignment = "none" right alignment = "right" left alignment = "left" ) @@ -24,7 +25,7 @@ type alignment string func (a alignment) Valid() bool { switch a { - case defaultAlignment, right, left: + case defaultAlignment, right, left, alignmentNone: return true default: return false