diff --git a/parser/blocks.go b/parser/blocks.go index 441b162..b8a9b38 100644 --- a/parser/blocks.go +++ b/parser/blocks.go @@ -70,10 +70,5 @@ func ExtractBlocks(template string) ([]blocks.TemplateBlock, error) { curlyIndex = nextCurlyIndex } - // var lastBlock = out[len(out)-1] - // if lastBlock.End == 0 { - // out = out[:len(out)-1] - // } - return out, nil } diff --git a/parser/blocks/list_block.go b/parser/blocks/block_list.go similarity index 69% rename from parser/blocks/list_block.go rename to parser/blocks/block_list.go index a9e2f4c..a6c98a4 100644 --- a/parser/blocks/list_block.go +++ b/parser/blocks/block_list.go @@ -1,10 +1,5 @@ package blocks -import "fmt" - func (b TemplateBlock) ParseListBlock(input string) (key string, value any, error error) { - - fmt.Printf("Parsing List: '%q'", input) - return "", nil, nil } diff --git a/parser/blocks/yaml_block.go b/parser/blocks/block_yaml.go similarity index 100% rename from parser/blocks/yaml_block.go rename to parser/blocks/block_yaml.go diff --git a/parser/blocks/blocks.go b/parser/blocks/blocks.go index c4403ef..91632c5 100644 --- a/parser/blocks/blocks.go +++ b/parser/blocks/blocks.go @@ -1,7 +1,6 @@ package blocks import ( - "fmt" "strings" ) @@ -11,7 +10,7 @@ type TemplateType int const ( InvalidTemplate TemplateType = iota ShortTemplate - LongTemplate + ExtendedTemplate ) // DetectTemplateType checks if the template is short or long. @@ -36,36 +35,12 @@ func DetectTemplateType(tmpl string) TemplateType { // } if strings.Contains(trimmed, "\n") && (strings.Contains(trimmed, "path:") || strings.Contains(trimmed, "codec:")) { - return LongTemplate + return ExtendedTemplate } return InvalidTemplate } -// CodecType represents the type of codec used to encode/render a value -type CodecType string - -const ( - CodecText CodecType = "text" - CodecNumber CodecType = "number" - CodecYaml CodecType = "yaml" - CodecList CodecType = "list" -) - -func parseCodecType(input string) (CodecType, error) { - switch input { - case "number": - return CodecNumber, nil - case "yaml": - return CodecYaml, nil - case "list": - return CodecList, nil - case "text": - return CodecText, nil - } - return CodecText, fmt.Errorf("unknown codec: '%s'", input) -} - type BlockType string const ( @@ -73,11 +48,18 @@ const ( MatchingBlock BlockType = "matching" // everything outside data blocks ) +type BlockField struct { + Path string + CodecType CodecType + Required bool +} + type TemplateBlock struct { Type BlockType Path string Codec CodecType Required bool + Fields []BlockField content string } diff --git a/parser/blocks/codecs.go b/parser/blocks/codecs.go new file mode 100644 index 0000000..3b5851e --- /dev/null +++ b/parser/blocks/codecs.go @@ -0,0 +1,30 @@ +package blocks + +import "fmt" + +// CodecType represents the type of codec used to encode/render a value +type CodecType string + +const ( + CodecText CodecType = "text" + CodecNumber CodecType = "number" + CodecYaml CodecType = "yaml" + CodecList CodecType = "list" + CodecConst CodecType = "const" +) + +func parseCodecType(input string) (CodecType, error) { + switch input { + case "number": + return CodecNumber, nil + case "yaml": + return CodecYaml, nil + case "list": + return CodecList, nil + case "text": + return CodecText, nil + case "const": + return CodecConst, nil + } + return CodecText, fmt.Errorf("unknown codec: '%s'", input) +} diff --git a/parser/blocks/template.go b/parser/blocks/template.go index 69b01f1..39d4338 100644 --- a/parser/blocks/template.go +++ b/parser/blocks/template.go @@ -71,7 +71,6 @@ func parseYamlTemplate(input string) (block TemplateBlock, err error) { dec.KnownFields(true) if err := dec.Decode(&blk); err != nil { - fmt.Printf("Failed to parse:\n---\n%s\n---\n", cleaned) return block, err } @@ -79,18 +78,46 @@ func parseYamlTemplate(input string) (block TemplateBlock, err error) { return block, fmt.Errorf("missing top-level 'path'") } + if blk.Codec == "" { + blk.Codec = "text" + } + codec, err := parseCodecType(blk.Codec) if err != nil { return block, fmt.Errorf("failed to parse codec: %w", err) } + var fields []BlockField + + for _, field := range blk.Fields { + if field.Path == "" { + return block, fmt.Errorf("failed to parse field: %v", field) + } + + if field.Codec == "" { + field.Codec = "text" + } + + fieldCodec, err := parseCodecType(field.Codec) + if err != nil { + return block, fmt.Errorf("failed to parse codec: %w", err) + } + + fields = append(fields, BlockField{ + Path: field.Path, + CodecType: fieldCodec, + Required: field.Required, + }) + + } + return TemplateBlock{ Type: DataBlock, Path: blk.Path, Codec: codec, + Fields: fields, content: input, }, nil - } func ParseTemplateBlock(template string, blockType BlockType) (block TemplateBlock, err error) { @@ -102,17 +129,13 @@ func ParseTemplateBlock(template string, blockType BlockType) (block TemplateBlo }, nil } - block.Type = DataBlock - block.content = template - - templateType := DetectTemplateType(template) - if templateType == InvalidTemplate { - return block, fmt.Errorf("Invalid Template") - } - - if templateType == ShortTemplate { + switch DetectTemplateType(template) { + case ShortTemplate: return parseShortTemplate(template) + case ExtendedTemplate: + return parseYamlTemplate(template) } - return parseYamlTemplate(template) + return block, fmt.Errorf("Invalid Template") + } diff --git a/registry/templates/recipe.marka b/registry/templates/recipe.marka index a02869c..0bb0ae9 100644 --- a/registry/templates/recipe.marka +++ b/registry/templates/recipe.marka @@ -4,26 +4,15 @@ codec: yaml fields: - path: name - codec: text - required: true - path: image - codec: text - required: true - path: author.@type codec: const value: Person - path: author.name - codec: text - path: datePublished - codec: text - - path: description - codec: text - path: prepTime - codec: text - path: cookTime - codec: text - path: recipeYield - codec: text } ---