diff options
Diffstat (limited to 'skate/map.go')
-rw-r--r-- | skate/map.go | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/skate/map.go b/skate/map.go index 9d3c98d..d6e37be 100644 --- a/skate/map.go +++ b/skate/map.go @@ -25,10 +25,11 @@ type TitleDoc struct { } // PartialDoc for docs, that do not have DOI or title. E.g. we found 49701699 -// (NCVY), 36401044 (NCVYU), 29668363 (NCUY), and so on. +// (NCVY), 36401044 (NCVYU), 29668363 (NCUY), and so on. Some examples: XXX type PartialDoc struct { ContainerName string `json:"container_name"` Contribs []struct { + // XXX: Need a way to sensibly compare sets of author names. RawName string `json:"raw_name"` } `json:"contribs"` Volume string `json:"volume"` @@ -40,17 +41,29 @@ type PartialDoc struct { // doc). We want fields, but we do not want to bake in TSV into each function. type Mapper func([]byte) ([][]byte, error) -// AsTSV serializes the result of a field mapper as TSV. This is a slim adapter, -// e.g. to parallel.Processor, which expects this function signature. +// AsTSV serializes the result of a field mapper as TSV. This is a slim +// adapter, e.g. to parallel.Processor, which expects this function signature. +// A newline will be appended, if not there already. func (f Mapper) AsTSV(p []byte) ([]byte, error) { - fields, err := f(p) - if err != nil { + var ( + fields [][]byte + err error + b []byte + ) + if fields, err = f(p); err != nil { return nil, err } - return bytes.Join(fields, bTab), nil + if len(fields) == 0 { + return nil, nil + } + b = bytes.Join(fields, bTab) + if len(b) > 0 && !bytes.HasSuffix(b, bNewline) { + b = append(b, bNewline...) + } + return b, nil } -// WithPrefix adds a given prefix to the first element. +// WithPrefix is a "mapper middleware", adding a given prefix to the first field. func WithPrefix(f Mapper, prefix string) Mapper { return func(p []byte) ([][]byte, error) { fields, err := f(p) @@ -65,6 +78,31 @@ func WithPrefix(f Mapper, prefix string) Mapper { } } +// WithBestEffort will not fail on an error. +func WithBestEffort(f Mapper) Mapper { + return func(p []byte) ([][]byte, error) { + if fields, err := f(p); err != nil { + return nil, nil + } else { + return fields, err + } + } +} + +// WithSkipOnEmpty ignores results where the value at a given field is empty. +func WithSkipOnEmpty(f Mapper, index int) Mapper { + return func(p []byte) ([][]byte, error) { + fields, err := f(p) + if err != nil { + return nil, err + } + if index < len(fields) && len(fields[index]) == 0 { + return nil, nil + } + return fields, err + } +} + // NameOf returns name of value, e.g. the name of a function. func NameOf(f interface{}) string { v := reflect.ValueOf(f) |