Skip to content

Commit

Permalink
Merge pull request #2 from tuan78/chore/flatten-nil-value
Browse files Browse the repository at this point in the history
chore: handle flattening with nil value
  • Loading branch information
tuan78 authored Jul 28, 2022
2 parents 6a8796f + 924e69c commit f0d9b53
Show file tree
Hide file tree
Showing 8 changed files with 244 additions and 80 deletions.
10 changes: 7 additions & 3 deletions csv_writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@ import (

// A CsvWriter writes records using CSV encoding.
type CsvWriter struct {
Delimiter *rune // Field delimiter. If nil, it uses default value from csv.NewWriter
UseCRLF bool // True to use \r\n as the line terminator
writer io.Writer
// Field delimiter. If nil, it uses default value from csv.NewWriter
Delimiter *rune

// True to use \r\n as the line terminator
UseCRLF bool

writer io.Writer
}

// NewCsvWriter returns a new CsvWriter that writes to w.
Expand Down
7 changes: 5 additions & 2 deletions json_converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ import (

// A ToCsvOption converts a JSON Array to CSV data.
type ToCsvOption struct {
FlattenOption *FlattenOption // Set it to apply JSON flattening
BaseHeaders CsvRow // Base CSV headers used to add before dynamic headers
// Set it to apply JSON flattening
FlattenOption *FlattenOption

// Base CSV headers used to add before dynamic headers
BaseHeaders CsvRow
}

// ToCsv converts a JsonArray to CsvData with given op.
Expand Down
49 changes: 42 additions & 7 deletions json_flattener.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,53 @@ import (
)

const (
FlattenLevelUnlimited = -1 // Set it to FlattenOption.Level for unlimited flattening
FlattenLevelNonNested = 0 // Set it to FlattenOption.Level for non-nested flattening (equivalent to non-flattening)
// Set it to FlattenOption.Level for unlimited flattening.
FlattenLevelUnlimited = -1

// Set it to FlattenOption.Level for non-nested flattening
// (equivalent to non-flattening).
FlattenLevelNonNested = 0

// Set it to FlattenOption.Level for default level flattening
// (equivalent to FlattenLevelUnlimited).
FlattenLevelDefault = FlattenLevelUnlimited
)

// Set it to FlattenOption.Gap for default gap flattening.
const FlattenGapDefault = "__"

// A FlattenOption is for JSON object flattening.
type FlattenOption struct {
Level int // Level of flattening, it can be FlattenLevelUnlimited, FlattenLevelNonNested or an int value in [1..n]
Gap string // A gap between nested JSON and its parent JSON. It will be used when merging nested JSON's key with parent JSON's key
SkipMap bool // Skip Map type (typically JSON Object type) from flattening process
SkipArray bool // Skip Array type (JSON array, string array, int array, float array, etc.) from flattening process
// Level of flattening, it can be FlattenLevelUnlimited,
// FlattenLevelNonNested or an int value in [1..n]
Level int

// A gap between nested JSON and its parent JSON.
// It will be used when merging nested JSON's key with parent JSON's key
Gap string

// Skip Map type (typically JSON Object type) from flattening process
SkipMap bool

// Skip Array type (JSON array, string array, int array, float array, etc.)
// from flattening process
SkipArray bool
}

// FlattenJsonObject flattens obj with given op.
func DefaultFlattenOption() *FlattenOption {
return &FlattenOption{
Level: FlattenLevelDefault,
Gap: FlattenGapDefault,
}
}

// FlattenJsonObject flattens obj with given op. If op is nil,
// it will use op value from DefaultFlattenOption instead.
func FlattenJsonObject(obj JsonObject, op *FlattenOption) {
if op == nil {
op = DefaultFlattenOption()
}

kset := make(map[string]struct{})
ks := make([]string, 0)
for k := range obj {
Expand Down Expand Up @@ -67,6 +100,8 @@ func extractJsonObject(k string, refval *reflect.Value, obj JsonObject, kset map
newK := fmt.Sprintf("%s[%v]", k, i)
extractJsonObject(newK, &nv, obj, kset, op, curLvl+1)
}
case reflect.Invalid:
obj[k] = nil
default:
obj[k] = refval.Interface()
}
Expand Down
Loading

0 comments on commit f0d9b53

Please sign in to comment.