Skip to content

Commit

Permalink
feat: Finalize 2.0 ctx api
Browse files Browse the repository at this point in the history
  • Loading branch information
Olian04 committed Jun 19, 2024
1 parent c237366 commit 5b29219
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 157 deletions.
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,9 @@ import handles/ctx
pub fn main() {
let assert Ok(template) = handles.prepare("Hello {{name}}")
let assert Ok(string) =
handles.run(
template,
[ctx.Prop("name", ctx.Str("Oliver"))]
)
handles.run(template, ctx.Dict([ctx.Prop("name", ctx.Str("Oliver"))]))
io.println(string)
io.debug(string)
}
```

Expand All @@ -38,10 +35,18 @@ A property tag is used to access properties passed into the template engine and
Values accessed by a property tag must be of type `String`, `Int`, or `Float`, or it will result in a runtime error.
Accessing a property which was not passed into the template engine will result in a runtime error.

A property tag can refer to a nested property with `.` separating keys in nested dicts.

```handlebars
{{some.property.path}}
```

A property can also refer to the current context element by passing a single `.`.

```handlebars
{{.}}
```

### Block tags

A block tag is used to temporarily alter the behavior of the templating engine.
Expand Down
4 changes: 2 additions & 2 deletions src/handles.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ pub fn prepare(template: String) -> Result(Template, error.TokenizerError) {

pub fn run(
template: Template,
root_ctx: List(ctx.Prop),
ctx: ctx.Value,
) -> Result(String, error.RuntimeError) {
let Template(ast) = template
engine.run(ast, ctx.Dict(root_ctx), string_builder.new())
engine.run(ast, ctx, string_builder.new())
}
91 changes: 0 additions & 91 deletions src/handles/ctx.gleam
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
import gleam/dict
import gleam/dynamic
import gleam/list

pub type Prop {
Prop(key: String, value: Value)
}
Expand All @@ -14,90 +10,3 @@ pub type Value {
Dict(value: List(Prop))
List(value: List(Value))
}

/// Transforms String, Int, Float, Bool, List, & Dict to their coresponding ctx.Value type.
///
/// Anny other types will panic
///
/// ## Examples
///
/// ```gleam
/// import handles/ctx
///
/// ctx.from("Hello World")
/// // -> ctx.Str("Hello World")
/// ```
///
/// ```gleam
/// ctx.from(42)
/// // -> ctx.Int(42)
/// ```
///
/// ```gleam
/// ctx.from(3.14)
/// // -> ctx.Float(3.14)
/// ```
///
/// ```gleam
/// ctx.from([1, 2, 3])
/// // -> ctx.List([ctx.Int(1), ctx.Int(2), ctx.Int(3)])
/// ```
///
/// ```gleam
/// ctx.from([
/// 42 |> dynamic.from,
/// 3.14 |> dynamic.from,
/// "Hello" |> dynamic.from,
/// ])
/// // -> ctx.List([ctx.Int(42), ctx.Float(3.14), ctx.Str("Hello")])
/// ```
pub fn from(value: a) -> Value {
from_dynamic(value |> dynamic.from)
}

fn from_dynamic(value: dynamic.Dynamic) -> Value {
case value |> dynamic.classify {
"String" -> {
let assert Ok(val) = value |> dynamic.string
Str(val)
}
"Int" -> {
let assert Ok(val) = value |> dynamic.int
Int(val)
}
"Float" -> {
let assert Ok(val) = value |> dynamic.float
Float(val)
}
"Bool" -> {
let assert Ok(val) = value |> dynamic.bool
Bool(val)
}
"Dict" -> {
let assert Ok(val) =
value |> dynamic.dict(dynamic.string, dynamic.dynamic)
from_dict(val, from_dynamic)
}
"List" -> {
let assert Ok(val) = value |> dynamic.list(dynamic.dynamic)
from_list(val, from_dynamic)
}
_ -> panic as "Unable to construct ctx from dynamic value"
}
}

fn from_dict(
source: dict.Dict(String, a),
value_mapper: fn(a) -> Value,
) -> Value {
source
|> dict.to_list
|> list.map(fn(it) { Prop(it.0, value_mapper(it.1)) })
|> Dict
}

fn from_list(source: List(a), value_mapper: fn(a) -> Value) -> Value {
source
|> list.map(value_mapper)
|> List
}
24 changes: 13 additions & 11 deletions test/api_test.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,26 @@ import handles/ctx
pub fn api_hello_world_test() {
handles.prepare("Hello {{name}}!")
|> should.be_ok
|> handles.run([ctx.Prop("name", ctx.Str("Oliver"))])
|> handles.run(ctx.Dict([ctx.Prop("name", ctx.Str("Oliver"))]))
|> should.be_ok
|> should.equal("Hello Oliver!")
}

pub fn api_knattarna_test() {
handles.prepare("{{#each knattarna}}Hello {{name}}\n{{/each}}")
|> should.be_ok
|> handles.run([
ctx.Prop(
"knattarna",
ctx.List([
ctx.Dict([ctx.Prop("name", ctx.Str("Knatte"))]),
ctx.Dict([ctx.Prop("name", ctx.Str("Fnatte"))]),
ctx.Dict([ctx.Prop("name", ctx.Str("Tjatte"))]),
]),
),
])
|> handles.run(
ctx.Dict([
ctx.Prop(
"knattarna",
ctx.List([
ctx.Dict([ctx.Prop("name", ctx.Str("Knatte"))]),
ctx.Dict([ctx.Prop("name", ctx.Str("Fnatte"))]),
ctx.Dict([ctx.Prop("name", ctx.Str("Tjatte"))]),
]),
),
]),
)
|> should.be_ok
|> should.equal(
"Hello Knatte
Expand Down
48 changes: 0 additions & 48 deletions test/unit_tests/ctx_test.gleam
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import gleam/dict
import gleam/dynamic
import gleam/iterator
import gleeunit/should
import handles/ctx
Expand Down Expand Up @@ -30,49 +28,3 @@ pub fn drill_deep_test() {
|> should.be_ok
|> should.equal(ctx.Str(expected_string))
}

pub fn from_string_test() {
ctx.from("foo")
|> should.equal(ctx.Str("foo"))
}

pub fn from_int_test() {
ctx.from(42)
|> should.equal(ctx.Int(42))
}

pub fn from_float_test() {
ctx.from(3.14)
|> should.equal(ctx.Float(3.14))
}

pub fn from_bool_test() {
ctx.from(True)
|> should.equal(ctx.Bool(True))
}

pub fn from_list_test() {
ctx.from([1, 2, 3])
|> should.equal(ctx.List([ctx.Int(1), ctx.Int(2), ctx.Int(3)]))
}

pub fn from_dict_test() {
ctx.from(
dict.new()
|> dict.insert("first", 1)
|> dict.insert("second", 2)
|> dict.insert("third", 3),
)
|> should.equal(
ctx.Dict([
ctx.Prop("first", ctx.Int(1)),
ctx.Prop("second", ctx.Int(2)),
ctx.Prop("third", ctx.Int(3)),
]),
)
}

pub fn from_mixed_types_test() {
ctx.from([42 |> dynamic.from, 3.14 |> dynamic.from, "Hello" |> dynamic.from])
|> should.equal(ctx.List([ctx.Int(42), ctx.Float(3.14), ctx.Str("Hello")]))
}

0 comments on commit 5b29219

Please sign in to comment.