-module(gleeam_code@init).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gleeam_code/init.gleam").
-export([run/2]).
-file("src/gleeam_code/init.gleam", 184).
-spec result_try(
{ok, nil} | {error, binary()},
fun((nil) -> {ok, nil} | {error, binary()})
) -> {ok, nil} | {error, binary()}.
result_try(Result, Next) ->
case Result of
{ok, _} ->
Next(nil);
{error, Err} ->
{error, Err}
end.
-file("src/gleeam_code/init.gleam", 194).
-spec create_file(binary(), binary(), binary(), fun((binary()) -> nil)) -> {ok,
nil} |
{error, binary()}.
create_file(Path, Content, Label, Print) ->
case gleeam_code@internal@file:exists(Path) of
true ->
Print(
<<<<" "/utf8, Label/binary>>/binary,
" already exists, skipping"/utf8>>
),
{ok, nil};
false ->
case gleeam_code@internal@file:write(Path, Content) of
{ok, _} ->
Print(<<" Created "/utf8, Label/binary>>),
{ok, nil};
{error, Err} ->
{error,
<<<<<<"Failed to create "/utf8, Label/binary>>/binary,
": "/utf8>>/binary,
(gleeam_code@internal@file:describe_error(Err))/binary>>}
end
end.
-file("src/gleeam_code/init.gleam", 219).
-spec create_solutions_dir(binary(), binary(), fun((binary()) -> nil)) -> {ok,
nil} |
{error, binary()}.
create_solutions_dir(Path, Label, Print) ->
case gleeam_code@internal@file:dir_exists(Path) of
true ->
Print(
<<<<" "/utf8, Label/binary>>/binary,
" already exists, skipping"/utf8>>
),
{ok, nil};
false ->
case gleeam_code@internal@file:mkdir(Path) of
{ok, _} ->
Print(<<" Created "/utf8, Label/binary>>),
{ok, nil};
{error, Err} ->
{error,
<<<<<<"Failed to create "/utf8, Label/binary>>/binary,
": "/utf8>>/binary,
(gleeam_code@internal@file:describe_error(Err))/binary>>}
end
end.
-file("src/gleeam_code/init.gleam", 243).
-spec create_glc_toml(binary(), fun((binary()) -> nil)) -> {ok, nil} |
{error, binary()}.
create_glc_toml(Path, Print) ->
case gleeam_code@internal@file:exists(Path) of
true ->
Print(<<" .glc.toml already exists, skipping"/utf8>>),
{ok, nil};
false ->
case gleeam_code@internal@file:write(
Path,
<<"# glc project config
[project]
solutions_dir = \"solutions\"
"/utf8>>
) of
{ok, _} ->
Print(<<" Created .glc.toml"/utf8>>),
{ok, nil};
{error, Err} ->
{error,
<<"Failed to create .glc.toml: "/utf8,
(gleeam_code@internal@file:describe_error(Err))/binary>>}
end
end.
-file("src/gleeam_code/init.gleam", 151).
-spec run(binary(), fun((binary()) -> nil)) -> {ok, nil} | {error, binary()}.
run(Base_dir, Print) ->
Gleam_toml = <<Base_dir/binary, "/gleam.toml"/utf8>>,
Src_solutions = <<Base_dir/binary, "/src/solutions"/utf8>>,
Test_solutions = <<Base_dir/binary, "/test/solutions"/utf8>>,
Glc_toml = <<Base_dir/binary, "/.glc.toml"/utf8>>,
Types_gleam = <<Base_dir/binary, "/src/types.gleam"/utf8>>,
Types_ffi = <<Base_dir/binary, "/src/types_ffi.erl"/utf8>>,
case gleeam_code@internal@file:exists(Gleam_toml) of
false ->
{error,
<<"gleam.toml not found. Run 'gleam new <project>' first."/utf8>>};
true ->
result_try(
create_solutions_dir(
Src_solutions,
<<"src/solutions/"/utf8>>,
Print
),
fun(_) ->
result_try(
create_solutions_dir(
Test_solutions,
<<"test/solutions/"/utf8>>,
Print
),
fun(_) ->
result_try(
create_glc_toml(Glc_toml, Print),
fun(_) ->
result_try(
create_file(
Types_gleam,
<<"import gleam/list
import gleam/option.{type Option, None, Some}
pub type TreeNode {
TreeNode(val: Int, left: Option(TreeNode), right: Option(TreeNode))
}
pub type ListNode {
ListNode(val: Int, next: Option(ListNode))
}
pub fn tree_from_level_order(values: List(Option(Int))) -> Option(TreeNode) {
case values {
[] -> None
[None, ..] -> None
[Some(root_val), ..rest] -> {
let #(flat, _) = bfs_assign([0], rest, [#(Some(root_val), -1, -1)], 1)
build_tree_from_flat(flat, 0)
}
}
}
fn bfs_assign(
queue: List(Int),
remaining: List(Option(Int)),
flat: List(#(Option(Int), Int, Int)),
next_idx: Int,
) -> #(List(#(Option(Int), Int, Int)), List(Option(Int))) {
case queue {
[] -> #(flat, remaining)
[parent_idx, ..rest_queue] -> {
let #(left_val, after_left) = take_next(remaining)
let #(right_val, after_right) = take_next(after_left)
let #(left_idx, flat2, queue2, idx2) = case left_val {
None -> #(-1, flat, rest_queue, next_idx)
Some(_) -> #(
next_idx,
list.append(flat, [#(left_val, -1, -1)]),
list.append(rest_queue, [next_idx]),
next_idx + 1,
)
}
let #(right_idx, flat3, queue3, idx3) = case right_val {
None -> #(-1, flat2, queue2, idx2)
Some(_) -> #(
idx2,
list.append(flat2, [#(right_val, -1, -1)]),
list.append(queue2, [idx2]),
idx2 + 1,
)
}
let flat4 =
list.index_map(flat3, fn(entry, i) {
case i == parent_idx {
True -> #(entry.0, left_idx, right_idx)
False -> entry
}
})
bfs_assign(queue3, after_right, flat4, idx3)
}
}
}
fn take_next(
values: List(Option(Int)),
) -> #(Option(Int), List(Option(Int))) {
case values {
[] -> #(None, [])
[v, ..rest] -> #(v, rest)
}
}
fn build_tree_from_flat(
flat: List(#(Option(Int), Int, Int)),
idx: Int,
) -> Option(TreeNode) {
case idx < 0 {
True -> None
False ->
case list.drop(flat, idx) {
[] -> None
[#(None, _, _), ..] -> None
[#(Some(val), left_idx, right_idx), ..] -> {
let left = build_tree_from_flat(flat, left_idx)
let right = build_tree_from_flat(flat, right_idx)
Some(TreeNode(val: val, left: left, right: right))
}
}
}
}
pub fn list_from_list(values: List(Int)) -> Option(ListNode) {
case values {
[] -> None
_ -> Some(do_list_from_list(values))
}
}
fn do_list_from_list(values: List(Int)) -> ListNode {
case values {
[] -> panic as \"unreachable: empty list\"
[x] -> ListNode(val: x, next: None)
[x, ..rest] -> ListNode(val: x, next: Some(do_list_from_list(rest)))
}
}
"/utf8>>,
<<"src/types.gleam"/utf8>>,
Print
),
fun(_) ->
create_file(
Types_ffi,
<<"-module(types_ffi).
-export([tree_to_record/1, tree_from_record/1,
list_to_record/1, list_from_record/1]).
-record(tree_node, {val = 0, left = null, right = null}).
-record(list_node, {val = 0, next = null}).
tree_to_record(none) ->
null;
tree_to_record({some, {tree_node, Val, Left, Right}}) ->
#tree_node{val = Val,
left = tree_to_record(Left),
right = tree_to_record(Right)};
tree_to_record({tree_node, Val, Left, Right}) ->
#tree_node{val = Val,
left = tree_to_record(Left),
right = tree_to_record(Right)}.
tree_from_record(null) ->
none;
tree_from_record(#tree_node{val = Val, left = Left, right = Right}) ->
{some, {tree_node, Val, tree_from_record(Left), tree_from_record(Right)}}.
list_to_record(none) ->
null;
list_to_record({some, {list_node, Val, Next}}) ->
#list_node{val = Val, next = list_to_record(Next)};
list_to_record({list_node, Val, Next}) ->
#list_node{val = Val, next = list_to_record(Next)}.
list_from_record(null) ->
none;
list_from_record(#list_node{val = Val, next = Next}) ->
{some, {list_node, Val, list_from_record(Next)}}.
"/utf8>>,
<<"src/types_ffi.erl"/utf8>>,
Print
)
end
)
end
)
end
)
end
)
end.