Skip to content

Commit

Permalink
fix!: not escaping strings
Browse files Browse the repository at this point in the history
  • Loading branch information
BrewingWeasel committed Nov 25, 2024
1 parent 65dc614 commit 4ff73d2
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 11 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

## Unreleased

- added support for prepending to lists [x, ..xs]
- added support for prepending to lists `[x, ..xs]`
- reworked generics for custom types to be more flexible and type-safe
- fix not escaping srtings

## v0.2.1 - 2024-11-13

Expand Down
11 changes: 2 additions & 9 deletions src/gleamgen/expression.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -686,12 +686,7 @@ pub fn render(
case expression.internal {
IntLiteral(value) -> value |> int.to_string() |> doc.from_string()
FloatLiteral(value) -> value |> float.to_string() |> doc.from_string()
StrLiteral(value) ->
doc.concat([
doc.from_string("\""),
doc.from_string(value),
doc.from_string("\""),
])
StrLiteral(value) -> render.escape_string(value)
BoolLiteral(True) -> doc.from_string("True")
BoolLiteral(False) -> doc.from_string("False")
NilLiteral -> doc.from_string("Nil")
Expand Down Expand Up @@ -749,9 +744,7 @@ fn render_panicking_expression(name: String, as_string: Option(String)) {
doc.concat([
doc.from_string(name <> " as"),
doc.space,
doc.from_string("\""),
doc.from_string(value),
doc.from_string("\""),
render.escape_string(value),
])
|> doc.group
None -> doc.from_string(name)
Expand Down
2 changes: 1 addition & 1 deletion src/gleamgen/matcher.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ pub fn to_unchecked(
pub fn render(matcher: Matcher(_, _)) -> render.Rendered {
case matcher {
Variable(name, ..) -> doc.from_string(name)
StringLiteral(literal, ..) -> doc.from_string("\"" <> literal <> "\"")
StringLiteral(literal, ..) -> render.escape_string(literal)
IntLiteral(literal, ..) -> literal |> int.to_string() |> doc.from_string()
BoolLiteral(True, ..) -> doc.from_string("True")
BoolLiteral(False, ..) -> doc.from_string("False")
Expand Down
23 changes: 23 additions & 0 deletions src/gleamgen/render.gleam
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import glam/doc
import gleam/string

pub type Rendered {
Render(doc: doc.Document)
Expand Down Expand Up @@ -48,3 +49,25 @@ pub fn body(
|> doc.append(doc.concat([between_brackets, doc.from_string("}")]))
|> doc.group
}

@internal
pub fn escape_string(string: String) -> doc.Document {
let escaped = do_escape_string(string, "")
doc.concat([
doc.from_string("\""),
doc.from_string(escaped),
doc.from_string("\""),
])
}

fn do_escape_string(original: String, escaped: String) -> String {
case string.pop_grapheme(original) {
Ok(#("\"", rest)) -> {
do_escape_string(rest, escaped <> "\\\"")
}
Ok(#(c, rest)) -> {
do_escape_string(rest, escaped <> c)
}
Error(Nil) -> escaped
}
}
21 changes: 21 additions & 0 deletions test/gleamgen_test.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,27 @@ pub fn simple_string_test() {
|> should.equal("\"hello\"")
}

pub fn string_escape_quote_test() {
expression.string("hel\"lo")
|> expression.render(render.default_context())
|> render.to_string()
|> should.equal("\"hel\\\"lo\"")
}

pub fn string_escape_slash_test() {
expression.string("hello\\hi")
|> expression.render(render.default_context())
|> render.to_string()
|> should.equal("\"hello\\hi\"")
}

pub fn empty_string_test() {
expression.string("")
|> expression.render(render.default_context())
|> render.to_string()
|> should.equal("\"\"")
}

pub fn simple_tuple_test() {
expression.tuple3(
expression.int(3),
Expand Down

0 comments on commit 4ff73d2

Please sign in to comment.