From fedfd70c501cb1c48fa223f18162d87987986b71 Mon Sep 17 00:00:00 2001 From: PedroEdiaz Date: Tue, 17 Jun 2025 11:43:52 -0600 Subject: [PATCH] Change map -> struct --- README.md | 4 ++-- decode.odin | 30 ++++++++++++++++++++++++++++++ template.odin => mustache.odin | 6 +++--- testing.odin | 33 ++++++++++++++++----------------- 4 files changed, 51 insertions(+), 22 deletions(-) create mode 100644 decode.odin rename template.odin => mustache.odin (96%) diff --git a/README.md b/README.md index 7e996a2..d0bcc0a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# Templateless -A lightweight, logicless templating library for the +# Mustacheless +A subset of {{mustache}}, logicless templating library for the [Odin programming language](https://odin-lang.org/). This library allows you to define templates using placeholder variables within strings and replace them with values from a provided dictionary. diff --git a/decode.odin b/decode.odin new file mode 100644 index 0000000..22cbf90 --- /dev/null +++ b/decode.odin @@ -0,0 +1,30 @@ +package mustache + +import "base:runtime" +import "core:reflect" +import "core:log" + +decode :: proc( v: any, key: string ) -> string { + + if v == nil do return "" + + ti := runtime.type_info_base(type_info_of(v.id)) + a := any{v.data, ti.id} + + #partial switch info in ti.variant { + + case runtime.Type_Info_Struct: + return decode( reflect.struct_field_value_by_name(v, key), ".") + + case runtime.Type_Info_String: + switch s in a { + case string: + return string(s) + case cstring: + return string(s) + } + + } + + return "" +} diff --git a/template.odin b/mustache.odin similarity index 96% rename from template.odin rename to mustache.odin index 0875346..c0caf5f 100644 --- a/template.odin +++ b/mustache.odin @@ -1,4 +1,4 @@ -package template +package mustache import "core:strings" @@ -20,7 +20,7 @@ A new string with all placeholders replaced by their corresponding values from the dictionary. If a key is missing in the dictionary, the placeholder is replaces with an empty string. */ -template :: proc(fmt: string, dict: map[string]string ) -> string { +mustache :: proc(fmt: string, v: any ) -> string { /* template works as a state machine, it manipulates `b` (returned string) and `key` (placeholder string), according to the states. No error @@ -52,7 +52,7 @@ template :: proc(fmt: string, dict: map[string]string ) -> string { strings.write_string(&b, "{}" ) s=.writing case .close_bracket: - strings.write_string(&b, dict[strings.to_string(key)] ) + strings.write_string(&b, decode(v, strings.to_string(key) )) strings.builder_reset(&key) s=.writing case .writing: diff --git a/testing.odin b/testing.odin index 95a77fe..2d96939 100644 --- a/testing.odin +++ b/testing.odin @@ -1,41 +1,41 @@ #+feature dynamic-literals #+private -package template +package mustache import "core:testing" @(test) test1 :: proc(t: ^testing.T){ fmt := "{" - tmp := template(fmt,{}) + tmp := mustache(fmt,{}) defer delete(tmp) testing.expect(t, tmp==fmt, tmp) } @(test) test2 :: proc(t: ^testing.T){ fmt := "}" - tmp := template(fmt,{}) + tmp := mustache(fmt,{}) defer delete(tmp) testing.expect(t, tmp==fmt, tmp) } @(test) test3 :: proc(t: ^testing.T){ fmt := "{{" - tmp := template(fmt,{}) + tmp := mustache(fmt,{}) defer delete(tmp) testing.expect(t, tmp==fmt, tmp) } @(test) test4 :: proc(t: ^testing.T){ fmt := "{{}" - tmp := template(fmt,{}) + tmp := mustache(fmt,{}) defer delete(tmp) testing.expect(t, tmp==fmt, tmp) } @(test) test5 :: proc(t: ^testing.T){ fmt := "{{}}" - tmp := template(fmt,{}) + tmp := mustache(fmt,{}) defer delete(tmp) testing.expect(t, tmp=="", tmp) } @@ -43,66 +43,65 @@ test5 :: proc(t: ^testing.T){ test6 :: proc(t: ^testing.T){ fmt := "{{foo}}" - dict := map[string]string{"foo"="var"} - defer delete(dict) + dict : struct { foo: string } = {"var"} - tmp := template(fmt, dict) + tmp := mustache(fmt, dict) defer delete(tmp) testing.expect(t, tmp=="var", tmp) } @(test) test7 :: proc(t: ^testing.T){ fmt := "{{{}}" - tmp := template(fmt,{}) + tmp := mustache(fmt,{}) defer delete(tmp) testing.expect(t, tmp=="", tmp) } @(test) test8 :: proc(t: ^testing.T){ fmt := "{{}}}" - tmp := template(fmt,{}) + tmp := mustache(fmt,{}) defer delete(tmp) testing.expect(t, tmp=="}", tmp) } @(test) test9 :: proc(t: ^testing.T){ fmt := "{{{}}}" - tmp := template(fmt,{}) + tmp := mustache(fmt,{}) defer delete(tmp) testing.expect(t, tmp=="}", tmp) } @(test) test10 :: proc(t: ^testing.T){ fmt := "{{} }}" - tmp := template(fmt,{}) + tmp := mustache(fmt,{}) defer delete(tmp) testing.expect(t, tmp=="", tmp) } @(test) test11 :: proc(t: ^testing.T){ fmt := "{{{} }}" - tmp := template(fmt,{}) + tmp := mustache(fmt,{}) defer delete(tmp) testing.expect(t, tmp=="", tmp) } @(test) test12 :: proc(t: ^testing.T){ fmt := " {{{} }}" - tmp := template(fmt,{}) + tmp := mustache(fmt,{}) defer delete(tmp) testing.expect(t, tmp==" ", tmp) } @(test) test13 :: proc(t: ^testing.T){ fmt := "{{{} }} " - tmp := template(fmt,{}) + tmp := mustache(fmt,{}) defer delete(tmp) testing.expect(t, tmp==" ", tmp) } @(test) test14 :: proc(t: ^testing.T){ fmt := "{{{}}}" - tmp := template(fmt,{}) + tmp := mustache(fmt,{}) defer delete(tmp) testing.expect(t, tmp=="}", tmp) }