irc: improve multi-line strings; complete list concat and dynamic attrs

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I64e53c68d90b62f3ca306865ceda32af6a6a6964
This commit is contained in:
raf 2026-02-22 21:49:58 +03:00
commit 8a093aa9e8
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
5 changed files with 204 additions and 61 deletions

View file

@ -64,6 +64,8 @@ struct Serializer::Impl {
return NodeType::HAS_ATTR;
if (node.holds<WithNode>())
return NodeType::WITH;
if (node.holds<ListNode>())
return NodeType::LIST;
if (node.holds<IfNode>())
return NodeType::IF;
if (node.holds<LetNode>())
@ -129,10 +131,16 @@ struct Serializer::Impl {
} else if (auto* n = node.get_if<AttrsetNode>()) {
write_u8(n->recursive ? 1 : 0);
write_u32(n->attrs.size());
for (const auto& [key, val] : n->attrs) {
write_string(key);
if (val)
write_node(*val);
for (const auto& binding : n->attrs) {
if (binding.is_dynamic()) {
write_u8(1); // Dynamic flag
write_node(*binding.dynamic_name);
} else {
write_u8(0); // Static flag
write_string(binding.static_name.value());
}
if (binding.value)
write_node(*binding.value);
}
} else if (auto* n = node.get_if<SelectNode>()) {
if (n->expr)
@ -155,6 +163,12 @@ struct Serializer::Impl {
write_node(*n->attrs);
if (n->body)
write_node(*n->body);
} else if (auto* n = node.get_if<ListNode>()) {
write_u32(n->elements.size());
for (const auto& elem : n->elements) {
if (elem)
write_node(*elem);
}
} else if (auto* n = node.get_if<IfNode>()) {
if (n->cond)
write_node(*n->cond);
@ -335,9 +349,16 @@ struct Deserializer::Impl {
uint32_t num_attrs = read_u32();
AttrsetNode attrs(recursive, line);
for (uint32_t i = 0; i < num_attrs; i++) {
std::string key = read_string();
auto val = read_node();
attrs.attrs.push_back({key, val});
uint8_t is_dynamic = read_u8();
if (is_dynamic) {
auto key_expr = read_node();
auto val = read_node();
attrs.attrs.push_back(AttrBinding(key_expr, val));
} else {
std::string key = read_string();
auto val = read_node();
attrs.attrs.push_back(AttrBinding(key, val));
}
}
return std::make_shared<Node>(std::move(attrs));
}
@ -363,6 +384,15 @@ struct Deserializer::Impl {
auto body = read_node();
return std::make_shared<Node>(WithNode(attrs, body, line));
}
case NodeType::LIST: {
uint32_t num_elements = read_u32();
std::vector<std::shared_ptr<Node>> elements;
elements.reserve(num_elements);
for (uint32_t i = 0; i < num_elements; i++) {
elements.push_back(read_node());
}
return std::make_shared<Node>(ListNode(std::move(elements), line));
}
case NodeType::IF: {
auto cond = read_node();
auto then_branch = read_node();