Skip to content

Commit

Permalink
organized codec
Browse files Browse the repository at this point in the history
  • Loading branch information
JFryy committed Aug 9, 2024
1 parent 8865936 commit db8daf0
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 66 deletions.
36 changes: 24 additions & 12 deletions codec/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ import (
"github.com/JFryy/qq/codec/markdown"
"github.com/JFryy/qq/codec/html"
"github.com/JFryy/qq/codec/gron"
"github.com/JFryy/qq/codec/hcl"
qqjson "github.com/JFryy/qq/codec/json"
"github.com/JFryy/qq/codec/line"
"github.com/JFryy/qq/codec/csv"
"github.com/JFryy/qq/codec/xml"
"github.com/JFryy/qq/codec/ini"
"bytes"
"github.com/alecthomas/chroma"
"github.com/alecthomas/chroma/formatters"
Expand Down Expand Up @@ -59,24 +64,31 @@ func GetEncodingType(fileType string) (EncodingType, error) {
return JSON, fmt.Errorf("unsupported file type: %v", fileType)
}

var md = markdown.Codec{}
var htm = html.Codec{}
var jsn = qqjson.Codec{} // wrapper for go-json marshal
var grn = gron.Codec{}
var (
md = markdown.Codec{}
htm = html.Codec{}
jsn = qqjson.Codec{} // wrapper for go-json marshal
grn = gron.Codec{}
hcltf = hcl.Codec{}
xmll = xml.Codec{}
inii = ini.Codec{}
lines = line.Codec{}
sv = csv.Codec{}
)
var SupportedFileTypes = []Encoding{
{JSON, json.Unmarshal, jsn.Marshal},
{YAML, yaml.Unmarshal, yaml.Marshal},
{YML, yaml.Unmarshal, yaml.Marshal},
{TOML, toml.Unmarshal, tomlMarshal},
{HCL, hclUnmarshal, hclMarshal},
{TF, hclUnmarshal, hclMarshal},
{CSV, csvUnmarshal, jsn.Marshal},
{XML, xmlUnmarshal, xmlMarshal},
{INI, iniUnmarshal, iniMarshal},
{TOML, toml.Unmarshal, toml.Marshal},
{HCL, hcltf.Unmarshal, hcltf.Marshal},
{TF, hcltf.Unmarshal, hcltf.Marshal},
{CSV, sv.Unmarshal, jsn.Marshal},
{XML, xmll.Unmarshal, xmll.Marshal},
{INI, inii.Unmarshal, inii.Marshal},
{GRON, grn.Unmarshal, grn.Marshal},
{HTML, htm.Unmarshal, jsn.Marshal},
{LINE, lineUnmarshal, jsn.Marshal},
{TXT, lineUnmarshal, jsn.Marshal},
{LINE, lines.Unmarshal, jsn.Marshal},
{TXT, lines.Unmarshal, jsn.Marshal},
{MD, md.Unmarshal, jsn.Marshal},
}

Expand Down
12 changes: 7 additions & 5 deletions codec/csv_codec.go → codec/csv/csv_codec.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package codec
package csv

import (
"bytes"
"encoding/csv"
"fmt"
"github.com/JFryy/qq/codec/util"
"github.com/goccy/go-json"
"io"
"strings"
"github.com/JFryy/qq/codec/util"
)

func detectDelimiter(input []byte) rune {
type Codec struct{}

func (c *Codec) detectDelimiter(input []byte) rune {
lines := bytes.Split(input, []byte("\n"))
if len(lines) < 2 {
return ','
Expand All @@ -35,8 +37,8 @@ func detectDelimiter(input []byte) rune {
return maxDelimiter
}

func csvUnmarshal(input []byte, v interface{}) error {
delimiter := detectDelimiter(input)
func (c *Codec) Unmarshal(input []byte, v interface{}) error {
delimiter := c.detectDelimiter(input)
r := csv.NewReader(strings.NewReader(string(input)))
r.Comma = delimiter
r.TrimLeadingSpace = true
Expand Down
35 changes: 14 additions & 21 deletions codec/hcl_codec.go → codec/hcl/hcl.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package codec
package hcl

import (
"fmt"
Expand All @@ -9,7 +9,9 @@ import (
"log"
)

func hclUnmarshal(input []byte, v interface{}) error {
type Codec struct{}

func (c *Codec) Unmarshal(input []byte, v interface{}) error {
opts := convert.Options{}
content, err := convert.Bytes(input, "json", opts)
if err != nil {
Expand All @@ -18,7 +20,7 @@ func hclUnmarshal(input []byte, v interface{}) error {
return json.Unmarshal(content, v)
}

func hclMarshal(v interface{}) ([]byte, error) {
func (c *Codec) Marshal(v interface{}) ([]byte, error) {
// Ensure the input is wrapped in a map if it's not already
var data map[string]interface{}
switch v := v.(type) {
Expand All @@ -29,36 +31,27 @@ func hclMarshal(v interface{}) ([]byte, error) {
"data": v,
}
}

// Convert map to HCL
hclData, err := convertMapToHCL(data)
hclData, err := c.convertMapToHCL(data)
if err != nil {
return nil, fmt.Errorf("error converting map to HCL: %v", err)
}

return hclData, nil
}

func convertMapToHCL(data map[string]interface{}) ([]byte, error) {
// Create a new HCL file
func (c *Codec) convertMapToHCL(data map[string]interface{}) ([]byte, error) {
f := hclwrite.NewEmptyFile()

// Create the root body of the file
rootBody := f.Body()

// Populate the body with the data
populateBody(rootBody, data)

// Return the HCL data
c.populateBody(rootBody, data)
return f.Bytes(), nil
}

func populateBody(body *hclwrite.Body, data map[string]interface{}) {
func (c *Codec) populateBody(body *hclwrite.Body, data map[string]interface{}) {
for key, value := range data {
switch v := value.(type) {
case map[string]interface{}:
block := body.AppendNewBlock(key, nil)
populateBody(block.Body(), v)
c.populateBody(block.Body(), v)
case string:
body.SetAttributeValue(key, cty.StringVal(v))
case int:
Expand All @@ -72,7 +65,7 @@ func populateBody(body *hclwrite.Body, data map[string]interface{}) {
case []interface{}:
tuple := make([]cty.Value, len(v))
for i, elem := range v {
tuple[i] = convertToCtyValue(elem)
tuple[i] = c.convertToCtyValue(elem)
}
body.SetAttributeValue(key, cty.TupleVal(tuple))
default:
Expand All @@ -81,7 +74,7 @@ func populateBody(body *hclwrite.Body, data map[string]interface{}) {
}
}

func convertToCtyValue(value interface{}) cty.Value {
func (c *Codec) convertToCtyValue(value interface{}) cty.Value {
switch v := value.(type) {
case string:
return cty.StringVal(v)
Expand All @@ -96,13 +89,13 @@ func convertToCtyValue(value interface{}) cty.Value {
case []interface{}:
tuple := make([]cty.Value, len(v))
for i, elem := range v {
tuple[i] = convertToCtyValue(elem)
tuple[i] = c.convertToCtyValue(elem)
}
return cty.TupleVal(tuple)
case map[string]interface{}:
vals := make(map[string]cty.Value)
for k, elem := range v {
vals[k] = convertToCtyValue(elem)
vals[k] = c.convertToCtyValue(elem)
}
return cty.ObjectVal(vals)
default:
Expand Down
8 changes: 5 additions & 3 deletions codec/ini_codec.go → codec/ini/ini_codec.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package codec
package ini

import (
"fmt"
Expand All @@ -8,7 +8,9 @@ import (
"github.com/JFryy/qq/codec/util"
)

func iniUnmarshal(input []byte, v interface{}) error {
type Codec struct{}

func (c *Codec) Unmarshal(input []byte, v interface{}) error {
cfg, err := ini.Load(input)
if err != nil {
return fmt.Errorf("error unmarshaling INI: %v", err)
Expand All @@ -29,7 +31,7 @@ func iniUnmarshal(input []byte, v interface{}) error {
return mapstructure.Decode(data, v)
}

func iniMarshal(v interface{}) ([]byte, error) {
func (c *Codec) Marshal(v interface{}) ([]byte, error) {
data, ok := v.(map[string]interface{})
if !ok {
return nil, fmt.Errorf("input data is not a map")
Expand Down
19 changes: 19 additions & 0 deletions codec/json.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package codec

import (
"bytes"
"github.com/goccy/go-json"
)

func jsonMarshal(v interface{}) ([]byte, error) {
var buf bytes.Buffer
encoder := json.NewEncoder(&buf)
encoder.SetEscapeHTML(false)
encoder.SetIndent("", " ")
err := encoder.Encode(v)
if err != nil {
return nil, err
}
encodedBytes := bytes.TrimSpace(buf.Bytes())
return encodedBytes, nil
}
6 changes: 4 additions & 2 deletions codec/line_codec.go → codec/line/line.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package codec
package line

import (
"fmt"
Expand All @@ -8,7 +8,9 @@ import (
"github.com/JFryy/qq/codec/util"
)

func lineUnmarshal(input []byte, v interface{}) error {
type Codec struct{}

func (c *Codec) Unmarshal(input []byte, v interface{}) error {
lines := strings.Split(strings.TrimSpace(string(input)), "\n")
var parsedLines []interface{}

Expand Down
16 changes: 0 additions & 16 deletions codec/toml_codec.go

This file was deleted.

16 changes: 9 additions & 7 deletions codec/xml_codec.go → codec/xml/xml.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package codec
package xml

import (
"fmt"
Expand All @@ -7,7 +7,9 @@ import (
"github.com/JFryy/qq/codec/util"
)

func xmlMarshal(v interface{}) ([]byte, error) {
type Codec struct{}

func (c *Codec) Marshal(v interface{}) ([]byte, error) {
switch v := v.(type) {
case map[string]interface{}:
mv := mxj.Map(v)
Expand All @@ -21,13 +23,13 @@ func xmlMarshal(v interface{}) ([]byte, error) {
}
}

func xmlUnmarshal(input []byte, v interface{}) error {
func (c *Codec) Unmarshal(input []byte, v interface{}) error {
mv, err := mxj.NewMapXml(input)
if err != nil {
return fmt.Errorf("error unmarshaling XML: %v", err)
}

parsedData := parseXMLValues(mv.Old())
parsedData := c.parseXMLValues(mv.Old())

// reflection of values required for type assertions on interface
rv := reflect.ValueOf(v)
Expand All @@ -40,16 +42,16 @@ func xmlUnmarshal(input []byte, v interface{}) error {
}

// infer the type of the value and parse it accordingly
func parseXMLValues(v interface{}) interface{} {
func (c *Codec) parseXMLValues(v interface{}) interface{} {
switch v := v.(type) {
case map[string]interface{}:
for key, val := range v {
v[key] = parseXMLValues(val)
v[key] = c.parseXMLValues(val)
}
return v
case []interface{}:
for i, val := range v {
v[i] = parseXMLValues(val)
v[i] = c.parseXMLValues(val)
}
return v
case string:
Expand Down

0 comments on commit db8daf0

Please sign in to comment.