mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-15 04:58:12 -07:00
global: snapshot
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user