global: snapshot

This commit is contained in:
nym21
2026-01-13 22:32:29 +01:00
parent 0c442b4a71
commit e77993fb76
61 changed files with 5047 additions and 5404 deletions
+45 -35
View File
@@ -20,6 +20,46 @@ fn path_suffix(name: &str) -> String {
}
}
/// Compute path expression from pattern mode and field part.
fn compute_path_expr<S: LanguageSyntax>(
syntax: &S,
pattern: &StructuralPattern,
field: &PatternField,
base_var: &str,
) -> String {
match pattern.get_field_part(&field.name) {
Some(part) => {
if pattern.is_suffix_mode() {
syntax.suffix_expr(base_var, part)
} else {
syntax.prefix_expr(part, base_var)
}
}
None => syntax.path_expr(base_var, &path_suffix(&field.name)),
}
}
/// Compute field value from path expression.
fn compute_field_value<S: LanguageSyntax>(
syntax: &S,
field: &PatternField,
metadata: &ClientMetadata,
path_expr: &str,
) -> String {
if metadata.is_pattern_type(&field.rust_type) {
syntax.constructor(&field.rust_type, path_expr)
} else if let Some(accessor) = metadata.find_index_set_pattern(&field.indexes) {
syntax.constructor(&accessor.name, path_expr)
} else if field.is_branch() {
syntax.constructor(&field.rust_type, path_expr)
} else {
panic!(
"Field '{}' has no matching pattern or index accessor. All metrics must be indexed.",
field.name
)
}
}
/// Generate a parameterized field using the language syntax.
///
/// This is used for pattern instances where fields use an accumulated
@@ -34,26 +74,8 @@ pub fn generate_parameterized_field<S: LanguageSyntax>(
) {
let field_name = syntax.field_name(&field.name);
let type_ann = metadata.field_type_annotation(field, pattern.is_generic, None, syntax.generic_syntax());
// Compute path expression from field position
let path_expr = pattern
.get_field_position(&field.name)
.map(|pos| syntax.position_expr(pos, "acc"))
.unwrap_or_else(|| syntax.path_expr("acc", &path_suffix(&field.name)));
let value = if metadata.is_pattern_type(&field.rust_type) {
syntax.constructor(&field.rust_type, &path_expr)
} else if let Some(accessor) = metadata.find_index_set_pattern(&field.indexes) {
syntax.constructor(&accessor.name, &path_expr)
} else if field.is_branch() {
// Non-pattern branch - instantiate the nested struct
syntax.constructor(&field.rust_type, &path_expr)
} else {
panic!(
"Field '{}' has no matching pattern or index accessor. All metrics must be indexed.",
field.name
)
};
let path_expr = compute_path_expr(syntax, pattern, field, "acc");
let value = compute_field_value(syntax, field, metadata, &path_expr);
writeln!(output, "{}", syntax.field_init(indent, &field_name, &type_ann, &value)).unwrap();
}
@@ -66,26 +88,14 @@ pub fn generate_tree_path_field<S: LanguageSyntax>(
output: &mut String,
syntax: &S,
field: &PatternField,
pattern: &StructuralPattern,
metadata: &ClientMetadata,
indent: &str,
) {
let field_name = syntax.field_name(&field.name);
let type_ann = metadata.field_type_annotation(field, false, None, syntax.generic_syntax());
let path_expr = syntax.path_expr("base_path", &path_suffix(&field.name));
let value = if metadata.is_pattern_type(&field.rust_type) {
syntax.constructor(&field.rust_type, &path_expr)
} else if let Some(accessor) = metadata.find_index_set_pattern(&field.indexes) {
syntax.constructor(&accessor.name, &path_expr)
} else if field.is_branch() {
// Non-pattern branch - instantiate the nested struct
syntax.constructor(&field.rust_type, &path_expr)
} else {
panic!(
"Field '{}' has no matching pattern or index accessor. All metrics must be indexed.",
field.name
)
};
let path_expr = compute_path_expr(syntax, pattern, field, "base_path");
let value = compute_field_value(syntax, field, metadata, &path_expr);
writeln!(output, "{}", syntax.field_init(indent, &field_name, &type_ann, &value)).unwrap();
}
+15 -3
View File
@@ -23,10 +23,12 @@ pub struct ChildContext<'a> {
pub base_result: PatternBaseResult,
/// Whether this is a leaf node.
pub is_leaf: bool,
/// Whether to use an inline type instead of a pattern factory (only meaningful for branches).
/// Whether to use an inline type instead of a pattern type (only meaningful for branches).
pub should_inline: bool,
/// The type name to use for inline branches.
pub inline_type_name: String,
/// Whether the pattern is parameterizable (has ::new() constructor).
pub is_parameterizable: bool,
}
/// Context for generating a tree node, returned by `prepare_tree_node`.
@@ -78,11 +80,20 @@ pub fn prepare_tree_node<'a>(
.map(|((child_name, child_node), (field, child_fields))| {
let is_leaf = matches!(child_node, TreeNode::Leaf(_));
let base_result = get_pattern_instance_base(child_node);
// For type annotations: use pattern type if ANY pattern matches
let matches_any_pattern = child_fields
.as_ref()
.is_some_and(|cf| metadata.matches_pattern(cf));
// For constructors: only use ::new() if parameterizable
let is_parameterizable = child_fields
.as_ref()
.is_some_and(|cf| metadata.is_parameterizable_fields(cf));
// should_inline is only meaningful for branches
let should_inline = !is_leaf && base_result.should_inline(is_parameterizable);
// should_inline determines if we generate an inline struct type
// We inline only if it's a branch AND doesn't match any pattern
let should_inline = !is_leaf && !matches_any_pattern;
// Inline type name (only used when should_inline is true)
let inline_type_name = if should_inline {
@@ -100,6 +111,7 @@ pub fn prepare_tree_node<'a>(
is_leaf,
should_inline,
inline_type_name,
is_parameterizable,
}
})
.collect();