mirror of
https://github.com/sbrow/thor.git
synced 2026-10-25 10:11:55 -04:00
feat: .Warning added to Error_Kind.
This commit is contained in:
@@ -1,5 +1,10 @@
|
|||||||
# TODOs
|
# TODOs
|
||||||
|
|
||||||
|
## Priority Unclear (Evaluate Later)
|
||||||
|
|
||||||
|
- [ ] instead of `warnings: [dynamic]Error` we should use `warnings: [dynamic; 8]Error`
|
||||||
|
- when limit reached, the template fails and stops rendering.
|
||||||
|
|
||||||
## General
|
## General
|
||||||
|
|
||||||
Remember to polish existing features before moving on to new ones.
|
Remember to polish existing features before moving on to new ones.
|
||||||
|
|||||||
+40
-31
@@ -23,8 +23,9 @@ Context_Stack :: [dynamic]any
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
Error_Kind :: enum {
|
Error_Kind :: enum {
|
||||||
Syntax, // parse-time: malformed template
|
Syntax, // parse-time: malformed template
|
||||||
Data, // render-time: template fine, data wrong (e.g. filter misuse)
|
Data, // render-time: template fine, data wrong (e.g. filter misuse)
|
||||||
|
Warning, // non-fatal: operation succeeded but user should know
|
||||||
}
|
}
|
||||||
|
|
||||||
Error_Body :: struct {
|
Error_Body :: struct {
|
||||||
@@ -176,6 +177,7 @@ render :: proc(
|
|||||||
data: any,
|
data: any,
|
||||||
partials: map[string]Template = nil,
|
partials: map[string]Template = nil,
|
||||||
allocator := context.allocator,
|
allocator := context.allocator,
|
||||||
|
warnings: ^[dynamic]Error = nil,
|
||||||
) -> (
|
) -> (
|
||||||
result: string,
|
result: string,
|
||||||
err: Error,
|
err: Error,
|
||||||
@@ -201,7 +203,7 @@ render :: proc(
|
|||||||
}
|
}
|
||||||
|
|
||||||
all_nodes := tmpl.nodes[:]
|
all_nodes := tmpl.nodes[:]
|
||||||
err = render_nodes(tmpl, all_nodes, &ctx, partials, &builder)
|
err = render_nodes(tmpl, all_nodes, &ctx, partials, &builder, warnings = warnings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
@@ -545,6 +547,7 @@ render_template :: proc(
|
|||||||
b: ^strings.Builder,
|
b: ^strings.Builder,
|
||||||
blocks: map[string]Block_Override,
|
blocks: map[string]Block_Override,
|
||||||
indent: string,
|
indent: string,
|
||||||
|
warnings: ^[dynamic]Error = nil,
|
||||||
) -> Error {
|
) -> Error {
|
||||||
if len(indent) > 0 {
|
if len(indent) > 0 {
|
||||||
state := Indent_State {
|
state := Indent_State {
|
||||||
@@ -552,9 +555,9 @@ render_template :: proc(
|
|||||||
at_line_start = false,
|
at_line_start = false,
|
||||||
}
|
}
|
||||||
strings.write_string(b, indent) // first line always gets indent
|
strings.write_string(b, indent) // first line always gets indent
|
||||||
return render_nodes(pt, pt.nodes[:], ctx, partials, b, blocks, &state)
|
return render_nodes(pt, pt.nodes[:], ctx, partials, b, blocks, &state, warnings)
|
||||||
}
|
}
|
||||||
return render_nodes(pt, pt.nodes[:], ctx, partials, b, blocks, nil)
|
return render_nodes(pt, pt.nodes[:], ctx, partials, b, blocks, nil, warnings)
|
||||||
}
|
}
|
||||||
|
|
||||||
write_indented :: proc(
|
write_indented :: proc(
|
||||||
@@ -598,6 +601,7 @@ render_nodes :: proc(
|
|||||||
b: ^strings.Builder,
|
b: ^strings.Builder,
|
||||||
blocks: map[string]Block_Override = nil,
|
blocks: map[string]Block_Override = nil,
|
||||||
indent_state: ^Indent_State = nil,
|
indent_state: ^Indent_State = nil,
|
||||||
|
warnings: ^[dynamic]Error = nil,
|
||||||
) -> Error {
|
) -> Error {
|
||||||
i := 0
|
i := 0
|
||||||
for i < len(nodes) {
|
for i < len(nodes) {
|
||||||
@@ -621,7 +625,7 @@ render_nodes :: proc(
|
|||||||
warn_unknown_key(current, ctx[:], node)
|
warn_unknown_key(current, ctx[:], node)
|
||||||
}
|
}
|
||||||
if len(node.filters) > 0 {
|
if len(node.filters) > 0 {
|
||||||
transformed, perr := apply_pipeline(val, node.filters[:], node.pos, ctx[:], current)
|
transformed, perr := apply_pipeline(val, node.filters[:], node.pos, ctx[:], current, warnings)
|
||||||
if perr != nil {
|
if perr != nil {
|
||||||
return tag_error(perr, current)
|
return tag_error(perr, current)
|
||||||
}
|
}
|
||||||
@@ -640,7 +644,7 @@ render_nodes :: proc(
|
|||||||
warn_unknown_key(current, ctx[:], node)
|
warn_unknown_key(current, ctx[:], node)
|
||||||
}
|
}
|
||||||
if len(node.filters) > 0 {
|
if len(node.filters) > 0 {
|
||||||
transformed, perr := apply_pipeline(val, node.filters[:], node.pos, ctx[:], current)
|
transformed, perr := apply_pipeline(val, node.filters[:], node.pos, ctx[:], current, warnings)
|
||||||
if perr != nil {
|
if perr != nil {
|
||||||
return tag_error(perr, current)
|
return tag_error(perr, current)
|
||||||
}
|
}
|
||||||
@@ -655,7 +659,7 @@ render_nodes :: proc(
|
|||||||
warn_unknown_key(current, ctx[:], node)
|
warn_unknown_key(current, ctx[:], node)
|
||||||
}
|
}
|
||||||
if len(node.filters) > 0 {
|
if len(node.filters) > 0 {
|
||||||
transformed, perr := apply_pipeline(val, node.filters[:], node.pos, ctx[:], current)
|
transformed, perr := apply_pipeline(val, node.filters[:], node.pos, ctx[:], current, warnings)
|
||||||
if perr != nil {
|
if perr != nil {
|
||||||
return tag_error(perr, current)
|
return tag_error(perr, current)
|
||||||
}
|
}
|
||||||
@@ -669,15 +673,16 @@ render_nodes :: proc(
|
|||||||
elem := extract_list_element(elem_info, data, j)
|
elem := extract_list_element(elem_info, data, j)
|
||||||
context_push(ctx, elem, current, node)
|
context_push(ctx, elem, current, node)
|
||||||
defer pop(ctx)
|
defer pop(ctx)
|
||||||
render_nodes(
|
render_nodes(
|
||||||
current,
|
current,
|
||||||
children,
|
children,
|
||||||
ctx,
|
ctx,
|
||||||
partials,
|
partials,
|
||||||
b,
|
b,
|
||||||
blocks,
|
blocks,
|
||||||
indent_state,
|
indent_state,
|
||||||
) or_return
|
warnings,
|
||||||
|
) or_return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
context_push(ctx, val, current, node)
|
context_push(ctx, val, current, node)
|
||||||
@@ -690,6 +695,7 @@ render_nodes :: proc(
|
|||||||
b,
|
b,
|
||||||
blocks,
|
blocks,
|
||||||
indent_state,
|
indent_state,
|
||||||
|
warnings,
|
||||||
) or_return
|
) or_return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -701,23 +707,24 @@ render_nodes :: proc(
|
|||||||
warn_unknown_key(current, ctx[:], node)
|
warn_unknown_key(current, ctx[:], node)
|
||||||
}
|
}
|
||||||
if len(node.filters) > 0 {
|
if len(node.filters) > 0 {
|
||||||
transformed, perr := apply_pipeline(val, node.filters[:], node.pos, ctx[:], current)
|
transformed, perr := apply_pipeline(val, node.filters[:], node.pos, ctx[:], current, warnings)
|
||||||
if perr != nil {
|
if perr != nil {
|
||||||
return tag_error(perr, current)
|
return tag_error(perr, current)
|
||||||
}
|
}
|
||||||
val = transformed
|
val = transformed
|
||||||
}
|
}
|
||||||
if !is_truthy(val) {
|
if !is_truthy(val) {
|
||||||
render_nodes(
|
render_nodes(
|
||||||
current,
|
current,
|
||||||
node.children,
|
node.children,
|
||||||
ctx,
|
ctx,
|
||||||
partials,
|
partials,
|
||||||
b,
|
b,
|
||||||
blocks,
|
blocks,
|
||||||
indent_state,
|
indent_state,
|
||||||
) or_return
|
warnings,
|
||||||
}
|
) or_return
|
||||||
|
}
|
||||||
i += 1 + len(node.children)
|
i += 1 + len(node.children)
|
||||||
|
|
||||||
case .Partial:
|
case .Partial:
|
||||||
@@ -730,7 +737,7 @@ render_nodes :: proc(
|
|||||||
if !found {
|
if !found {
|
||||||
warn_missing_partial(current, partials, node, name)
|
warn_missing_partial(current, partials, node, name)
|
||||||
} else {
|
} else {
|
||||||
render_template(pt, ctx, partials, b, nil, node.indent) or_return
|
render_template(pt, ctx, partials, b, nil, node.indent, warnings) or_return
|
||||||
if indent_state != nil {
|
if indent_state != nil {
|
||||||
indent_state.at_line_start = false
|
indent_state.at_line_start = false
|
||||||
}
|
}
|
||||||
@@ -765,6 +772,7 @@ render_nodes :: proc(
|
|||||||
&temp,
|
&temp,
|
||||||
content_blocks,
|
content_blocks,
|
||||||
nil,
|
nil,
|
||||||
|
warnings,
|
||||||
) or_return
|
) or_return
|
||||||
at_ls := true
|
at_ls := true
|
||||||
write_indented(b, node.indent, strings.to_string(temp), &at_ls)
|
write_indented(b, node.indent, strings.to_string(temp), &at_ls)
|
||||||
@@ -777,6 +785,7 @@ render_nodes :: proc(
|
|||||||
b,
|
b,
|
||||||
content_blocks,
|
content_blocks,
|
||||||
indent_state,
|
indent_state,
|
||||||
|
warnings,
|
||||||
) or_return
|
) or_return
|
||||||
}
|
}
|
||||||
i += 1 + len(node.children)
|
i += 1 + len(node.children)
|
||||||
@@ -789,7 +798,7 @@ render_nodes :: proc(
|
|||||||
warn_missing_partial(current, partials, node, node.key)
|
warn_missing_partial(current, partials, node, node.key)
|
||||||
} else {
|
} else {
|
||||||
warn_unmatched_block_overrides(current, pt, parent_children)
|
warn_unmatched_block_overrides(current, pt, parent_children)
|
||||||
render_template(pt, ctx, partials, b, merged, node.indent) or_return
|
render_template(pt, ctx, partials, b, merged, node.indent, warnings) or_return
|
||||||
if indent_state != nil {
|
if indent_state != nil {
|
||||||
indent_state.at_line_start = false
|
indent_state.at_line_start = false
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-22
@@ -221,14 +221,26 @@ apply_pipeline :: proc(
|
|||||||
pos: int,
|
pos: int,
|
||||||
ctx: []any,
|
ctx: []any,
|
||||||
tmpl: Template,
|
tmpl: Template,
|
||||||
|
warnings: ^[dynamic]Error = nil,
|
||||||
) -> (
|
) -> (
|
||||||
current: any,
|
current: any,
|
||||||
err: Error,
|
err: Error,
|
||||||
) {
|
) {
|
||||||
current = value
|
current = value
|
||||||
for &filter in filters {
|
for &filter in filters {
|
||||||
current = apply_filter(current, &filter, pos, ctx, tmpl) or_return
|
result, ferr := apply_filter(current, &filter, pos, ctx, tmpl)
|
||||||
log.debugf("applied: filter=%v before=%s after=%s pos=%d", filter, value, current, pos)
|
if ferr != nil {
|
||||||
|
b := body(ferr)
|
||||||
|
if b.kind != .Warning {
|
||||||
|
return result, ferr
|
||||||
|
}
|
||||||
|
if warnings != nil {
|
||||||
|
append(warnings, ferr)
|
||||||
|
} else {
|
||||||
|
log.warnf("%s", format_render_error(ferr, tmpl))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
current = result
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -438,6 +450,7 @@ take :: proc(
|
|||||||
elem_info, count, data := list_info(value)
|
elem_info, count, data := list_info(value)
|
||||||
is_list := elem_info != nil
|
is_list := elem_info != nil
|
||||||
from_start := from_start
|
from_start := from_start
|
||||||
|
warning: Error = nil
|
||||||
|
|
||||||
str: string
|
str: string
|
||||||
if !is_list {
|
if !is_list {
|
||||||
@@ -457,15 +470,14 @@ take :: proc(
|
|||||||
|
|
||||||
n := 1
|
n := 1
|
||||||
if !is_list && len(args) == 0 {
|
if !is_list && len(args) == 0 {
|
||||||
path := tmpl.path != "" ? tmpl.path : "<input>"
|
warning = Error_Body {
|
||||||
diag := format_tag_error(
|
msg = "defaulting to n=1 for string",
|
||||||
path,
|
pos = tag_pos,
|
||||||
tmpl.source,
|
kind = .Warning,
|
||||||
op_pos,
|
source = tmpl.source,
|
||||||
"defaulting to n=1 for string",
|
path = tmpl.path,
|
||||||
"consider specifying n explicitly",
|
hint = "consider specifying n explicitly",
|
||||||
)
|
}
|
||||||
log.warnf("%s", diag)
|
|
||||||
}
|
}
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
parsed, ok := strconv.parse_int(args[0])
|
parsed, ok := strconv.parse_int(args[0])
|
||||||
@@ -494,15 +506,14 @@ take :: proc(
|
|||||||
if n < 0 {
|
if n < 0 {
|
||||||
op_name := from_start ? "first" : "last"
|
op_name := from_start ? "first" : "last"
|
||||||
alt_name := from_start ? "last" : "first"
|
alt_name := from_start ? "last" : "first"
|
||||||
path := tmpl.path != "" ? tmpl.path : "<input>"
|
warning = Error_Body {
|
||||||
diag := format_tag_error(
|
msg = fmt.tprintf("%s %d is equivalent to %s %d", op_name, n, alt_name, 0 - n),
|
||||||
path,
|
pos = tag_pos,
|
||||||
tmpl.source,
|
kind = .Warning,
|
||||||
op_pos,
|
source = tmpl.source,
|
||||||
fmt.tprintf("%s %d is equivalent to %s %d", op_name, n, alt_name, 0 - n),
|
path = tmpl.path,
|
||||||
"consider using the clearer form",
|
hint = "consider using the clearer form",
|
||||||
)
|
}
|
||||||
log.warnf("%s", diag)
|
|
||||||
from_start = !from_start
|
from_start = !from_start
|
||||||
n = 0 - n
|
n = 0 - n
|
||||||
}
|
}
|
||||||
@@ -522,9 +533,9 @@ take :: proc(
|
|||||||
for j in start ..< end {
|
for j in start ..< end {
|
||||||
append(&result, extract_list_element(elem_info, data, j))
|
append(&result, extract_list_element(elem_info, data, j))
|
||||||
}
|
}
|
||||||
return result, nil
|
return any{new_clone(result, context.temp_allocator), typeid_of([dynamic]any)}, warning
|
||||||
} else {
|
} else {
|
||||||
return str[start:end], nil
|
return any{new_clone(str[start:end], context.temp_allocator), typeid_of(string)}, warning
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user