mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-06-16 01:39:44 -07:00
clients: snapshot
This commit is contained in:
@@ -379,10 +379,55 @@ pub fn generate_index_accessors(output: &mut String, patterns: &[IndexSetPattern
|
||||
return;
|
||||
}
|
||||
|
||||
writeln!(output, "// Index accessor factory functions\n").unwrap();
|
||||
writeln!(output, "// Index group constants and factory\n").unwrap();
|
||||
|
||||
for pattern in patterns {
|
||||
// Use 'readonly' to indicate these are getters (lazy evaluation)
|
||||
// Generate index array constants (e.g., _i1 = ["dateindex", "height"])
|
||||
for (i, pattern) in patterns.iter().enumerate() {
|
||||
write!(output, "const _i{} = [", i + 1).unwrap();
|
||||
for (j, index) in pattern.indexes.iter().enumerate() {
|
||||
if j > 0 {
|
||||
write!(output, ", ").unwrap();
|
||||
}
|
||||
write!(output, "\"{}\"", index.serialize_long()).unwrap();
|
||||
}
|
||||
writeln!(output, "];").unwrap();
|
||||
}
|
||||
writeln!(output).unwrap();
|
||||
|
||||
// Generate ONE generic metric pattern factory
|
||||
writeln!(
|
||||
output,
|
||||
r#"/**
|
||||
* Generic metric pattern factory.
|
||||
* @template T
|
||||
* @param {{BrkClientBase}} client
|
||||
* @param {{string}} name - The metric vec name
|
||||
* @param {{readonly string[]}} indexes - The supported indexes
|
||||
* @returns {{MetricPattern<T>}}
|
||||
*/
|
||||
function _mp(client, name, indexes) {{
|
||||
const by = {{}};
|
||||
for (const idx of indexes) {{
|
||||
Object.defineProperty(by, idx, {{
|
||||
get() {{ return _endpoint(client, name, idx); }},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
}});
|
||||
}}
|
||||
return {{
|
||||
name,
|
||||
by,
|
||||
indexes() {{ return indexes; }},
|
||||
get(index) {{ return indexes.includes(index) ? _endpoint(client, name, index) : undefined; }}
|
||||
}};
|
||||
}}
|
||||
"#
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Generate typedefs and thin wrapper functions
|
||||
for (i, pattern) in patterns.iter().enumerate() {
|
||||
// Generate typedef for type safety
|
||||
let by_fields: Vec<String> = pattern
|
||||
.indexes
|
||||
.iter()
|
||||
@@ -395,74 +440,29 @@ pub fn generate_index_accessors(output: &mut String, patterns: &[IndexSetPattern
|
||||
.collect();
|
||||
let by_type = format!("{{ {} }}", by_fields.join(", "));
|
||||
|
||||
writeln!(output, "/**").unwrap();
|
||||
writeln!(
|
||||
output,
|
||||
" * Metric pattern with index endpoints as lazy getters."
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(
|
||||
output,
|
||||
" * Access via property (.by.dateindex) or bracket notation (.by['dateindex'])."
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(output, " * @template T").unwrap();
|
||||
writeln!(
|
||||
output,
|
||||
" * @typedef {{{{ name: string, by: {}, indexes: () => Index[], get: (index: Index) => MetricEndpointBuilder<T>|undefined }}}} {}",
|
||||
"/** @template T @typedef {{{{ name: string, by: {}, indexes: () => Index[], get: (index: Index) => MetricEndpointBuilder<T>|undefined }}}} {} */",
|
||||
by_type, pattern.name
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(output, " */\n").unwrap();
|
||||
|
||||
writeln!(output, "/**").unwrap();
|
||||
writeln!(output, " * Create a {} accessor", pattern.name).unwrap();
|
||||
writeln!(output, " * @template T").unwrap();
|
||||
writeln!(output, " * @param {{BrkClientBase}} client").unwrap();
|
||||
writeln!(output, " * @param {{string}} name - The metric vec name").unwrap();
|
||||
writeln!(output, " * @returns {{{}<T>}}", pattern.name).unwrap();
|
||||
writeln!(output, " */").unwrap();
|
||||
writeln!(output, "function create{}(client, name) {{", pattern.name).unwrap();
|
||||
writeln!(output, " return {{").unwrap();
|
||||
writeln!(output, " name,").unwrap();
|
||||
writeln!(output, " by: {{").unwrap();
|
||||
|
||||
for (i, index) in pattern.indexes.iter().enumerate() {
|
||||
let index_name = index.serialize_long();
|
||||
let comma = if i < pattern.indexes.len() - 1 {
|
||||
","
|
||||
} else {
|
||||
""
|
||||
};
|
||||
writeln!(
|
||||
output,
|
||||
" get {}() {{ return _endpoint(client, name, '{}'); }}{}",
|
||||
index_name, index_name, comma
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
writeln!(output, " }},").unwrap();
|
||||
writeln!(output, " indexes() {{").unwrap();
|
||||
|
||||
write!(output, " return [").unwrap();
|
||||
for (i, index) in pattern.indexes.iter().enumerate() {
|
||||
if i > 0 {
|
||||
write!(output, ", ").unwrap();
|
||||
}
|
||||
write!(output, "'{}'", index.serialize_long()).unwrap();
|
||||
}
|
||||
writeln!(output, "];").unwrap();
|
||||
|
||||
writeln!(output, " }},").unwrap();
|
||||
writeln!(output, " get(index) {{").unwrap();
|
||||
writeln!(output, " if (this.indexes().includes(index)) {{").unwrap();
|
||||
writeln!(output, " return _endpoint(client, name, index);").unwrap();
|
||||
writeln!(output, " }}").unwrap();
|
||||
writeln!(output, " }}").unwrap();
|
||||
writeln!(output, " }};").unwrap();
|
||||
writeln!(output, "}}\n").unwrap();
|
||||
// Generate thin wrapper that calls the generic factory
|
||||
writeln!(
|
||||
output,
|
||||
"/** @template T @param {{BrkClientBase}} client @param {{string}} name @returns {{{}<T>}} */",
|
||||
pattern.name
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(
|
||||
output,
|
||||
"function create{}(client, name) {{ return _mp(client, name, _i{}); }}",
|
||||
pattern.name,
|
||||
i + 1
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
writeln!(output).unwrap();
|
||||
}
|
||||
|
||||
/// Generate structural pattern factory functions.
|
||||
|
||||
@@ -372,91 +372,75 @@ pub fn generate_index_accessors(output: &mut String, patterns: &[IndexSetPattern
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate static index tuples
|
||||
writeln!(output, "# Static index tuples").unwrap();
|
||||
for (i, pattern) in patterns.iter().enumerate() {
|
||||
write!(output, "_i{} = (", i + 1).unwrap();
|
||||
for (j, index) in pattern.indexes.iter().enumerate() {
|
||||
if j > 0 {
|
||||
write!(output, ", ").unwrap();
|
||||
}
|
||||
write!(output, "'{}'", index.serialize_long()).unwrap();
|
||||
}
|
||||
// Single-element tuple needs trailing comma
|
||||
if pattern.indexes.len() == 1 {
|
||||
write!(output, ",").unwrap();
|
||||
}
|
||||
writeln!(output, ")").unwrap();
|
||||
}
|
||||
writeln!(output).unwrap();
|
||||
|
||||
// Generate helper function
|
||||
writeln!(
|
||||
output,
|
||||
r#"def _ep(c: BrkClientBase, n: str, i: Index) -> MetricEndpointBuilder:
|
||||
return MetricEndpointBuilder(c, n, i)
|
||||
"#
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
writeln!(output, "# Index accessor classes\n").unwrap();
|
||||
|
||||
for pattern in patterns {
|
||||
for (i, pattern) in patterns.iter().enumerate() {
|
||||
let by_class_name = format!("_{}By", pattern.name);
|
||||
let idx_var = format!("_i{}", i + 1);
|
||||
|
||||
// Generate the By class with lazy endpoint methods
|
||||
// Generate the By class with compact methods
|
||||
writeln!(output, "class {}(Generic[T]):", by_class_name).unwrap();
|
||||
writeln!(output, " \"\"\"Index endpoint methods container.\"\"\"").unwrap();
|
||||
writeln!(output, " ").unwrap();
|
||||
writeln!(
|
||||
output,
|
||||
" def __init__(self, client: BrkClientBase, name: str):"
|
||||
" def __init__(self, c: BrkClientBase, n: str): self._c, self._n = c, n"
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(output, " self._client = client").unwrap();
|
||||
writeln!(output, " self._name = name").unwrap();
|
||||
writeln!(output).unwrap();
|
||||
|
||||
// Generate methods for each index
|
||||
for index in &pattern.indexes {
|
||||
let method_name = index_to_field_name(index);
|
||||
let index_name = index.serialize_long();
|
||||
writeln!(output, " def {}(self) -> MetricEndpointBuilder[T]:", method_name).unwrap();
|
||||
writeln!(
|
||||
output,
|
||||
" return MetricEndpointBuilder(self._client, self._name, '{}')",
|
||||
index_name
|
||||
" def {}(self) -> MetricEndpointBuilder[T]: return _ep(self._c, self._n, '{}')",
|
||||
method_name, index_name
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(output).unwrap();
|
||||
}
|
||||
writeln!(output).unwrap();
|
||||
|
||||
// Generate the main accessor class
|
||||
writeln!(output, "class {}(Generic[T]):", pattern.name).unwrap();
|
||||
writeln!(
|
||||
output,
|
||||
" \"\"\"Index accessor for metrics with {} indexes.\"\"\"",
|
||||
pattern.indexes.len()
|
||||
" def __init__(self, c: BrkClientBase, n: str): self._n, self.by = n, {}(c, n)",
|
||||
by_class_name
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(output, " ").unwrap();
|
||||
writeln!(
|
||||
output,
|
||||
" def __init__(self, client: BrkClientBase, name: str):"
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(output, " self._client = client").unwrap();
|
||||
writeln!(output, " self._name = name").unwrap();
|
||||
writeln!(
|
||||
output,
|
||||
" self.by: {}[T] = {}(client, name)",
|
||||
by_class_name, by_class_name
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(output).unwrap();
|
||||
writeln!(output, " @property").unwrap();
|
||||
writeln!(output, " def name(self) -> str:").unwrap();
|
||||
writeln!(output, " \"\"\"Get the metric name.\"\"\"").unwrap();
|
||||
writeln!(output, " return self._name").unwrap();
|
||||
writeln!(output).unwrap();
|
||||
writeln!(output, " def indexes(self) -> List[str]:").unwrap();
|
||||
writeln!(output, " \"\"\"Get the list of available indexes.\"\"\"").unwrap();
|
||||
write!(output, " return [").unwrap();
|
||||
for (i, index) in pattern.indexes.iter().enumerate() {
|
||||
if i > 0 {
|
||||
write!(output, ", ").unwrap();
|
||||
}
|
||||
write!(output, "'{}'", index.serialize_long()).unwrap();
|
||||
}
|
||||
writeln!(output, "]").unwrap();
|
||||
writeln!(output).unwrap();
|
||||
|
||||
// Generate get(index) method
|
||||
writeln!(output, " def get(self, index: Index) -> Optional[MetricEndpointBuilder[T]]:").unwrap();
|
||||
writeln!(output, " \"\"\"Get an endpoint builder for a specific index, if supported.\"\"\"").unwrap();
|
||||
for (i, index) in pattern.indexes.iter().enumerate() {
|
||||
let method_name = index_to_field_name(index);
|
||||
let index_name = index.serialize_long();
|
||||
if i == 0 {
|
||||
writeln!(output, " if index == '{}': return self.by.{}()", index_name, method_name).unwrap();
|
||||
} else {
|
||||
writeln!(output, " elif index == '{}': return self.by.{}()", index_name, method_name).unwrap();
|
||||
}
|
||||
}
|
||||
writeln!(output, " return None").unwrap();
|
||||
writeln!(output, " def name(self) -> str: return self._n").unwrap();
|
||||
writeln!(output, " def indexes(self) -> List[str]: return list({})", idx_var).unwrap();
|
||||
writeln!(
|
||||
output,
|
||||
" def get(self, index: Index) -> Optional[MetricEndpointBuilder[T]]: return _ep(self.by._c, self._n, index) if index in {} else None",
|
||||
idx_var
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(output).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,122 +375,84 @@ pub fn generate_index_accessors(output: &mut String, patterns: &[IndexSetPattern
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate static index arrays
|
||||
writeln!(output, "// Static index arrays").unwrap();
|
||||
for (i, pattern) in patterns.iter().enumerate() {
|
||||
write!(output, "const _I{}: &[Index] = &[", i + 1).unwrap();
|
||||
for (j, index) in pattern.indexes.iter().enumerate() {
|
||||
if j > 0 {
|
||||
write!(output, ", ").unwrap();
|
||||
}
|
||||
write!(output, "Index::{}", index).unwrap();
|
||||
}
|
||||
writeln!(output, "];").unwrap();
|
||||
}
|
||||
writeln!(output).unwrap();
|
||||
|
||||
// Generate helper function
|
||||
writeln!(
|
||||
output,
|
||||
r#"#[inline]
|
||||
fn _ep<T: DeserializeOwned>(c: &Arc<BrkClientBase>, n: &Arc<str>, i: Index) -> MetricEndpointBuilder<T> {{
|
||||
MetricEndpointBuilder::new(c.clone(), n.clone(), i)
|
||||
}}
|
||||
"#
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Generate index accessor structs
|
||||
writeln!(output, "// Index accessor structs\n").unwrap();
|
||||
|
||||
for pattern in patterns {
|
||||
for (i, pattern) in patterns.iter().enumerate() {
|
||||
let by_name = format!("{}By", pattern.name);
|
||||
let idx_const = format!("_I{}", i + 1);
|
||||
|
||||
// Generate the "By" struct with lazy endpoint methods
|
||||
writeln!(output, "/// Container for index endpoint methods.").unwrap();
|
||||
writeln!(output, "pub struct {}<T> {{", by_name).unwrap();
|
||||
writeln!(output, " client: Arc<BrkClientBase>,").unwrap();
|
||||
writeln!(output, " name: Arc<str>,").unwrap();
|
||||
writeln!(output, " _marker: std::marker::PhantomData<T>,").unwrap();
|
||||
writeln!(output, "}}\n").unwrap();
|
||||
|
||||
// Generate impl with methods for each index
|
||||
// Generate the "By" struct
|
||||
writeln!(output, "pub struct {}<T> {{ client: Arc<BrkClientBase>, name: Arc<str>, _marker: std::marker::PhantomData<T> }}", by_name).unwrap();
|
||||
writeln!(output, "impl<T: DeserializeOwned> {}<T> {{", by_name).unwrap();
|
||||
for index in &pattern.indexes {
|
||||
let method_name = index_to_field_name(index);
|
||||
writeln!(
|
||||
output,
|
||||
" pub fn {}(&self) -> MetricEndpointBuilder<T> {{",
|
||||
method_name
|
||||
" pub fn {}(&self) -> MetricEndpointBuilder<T> {{ _ep(&self.client, &self.name, Index::{}) }}",
|
||||
method_name, index
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(
|
||||
output,
|
||||
" MetricEndpointBuilder::new(self.client.clone(), self.name.clone(), Index::{})",
|
||||
index
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(output, " }}").unwrap();
|
||||
}
|
||||
writeln!(output, "}}\n").unwrap();
|
||||
|
||||
// Generate the main accessor struct
|
||||
writeln!(
|
||||
output,
|
||||
"/// Index accessor for metrics with {} indexes.",
|
||||
pattern.indexes.len()
|
||||
"pub struct {}<T> {{ name: Arc<str>, pub by: {}<T> }}",
|
||||
pattern.name, by_name
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(output, "pub struct {}<T> {{", pattern.name).unwrap();
|
||||
writeln!(output, " name: Arc<str>,").unwrap();
|
||||
writeln!(output, " pub by: {}<T>,", by_name).unwrap();
|
||||
writeln!(output, "}}\n").unwrap();
|
||||
|
||||
// Generate impl block with constructor
|
||||
writeln!(output, "impl<T: DeserializeOwned> {}<T> {{", pattern.name).unwrap();
|
||||
writeln!(
|
||||
output,
|
||||
" pub fn new(client: Arc<BrkClientBase>, name: String) -> Self {{"
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(output, " let name: Arc<str> = name.into();").unwrap();
|
||||
writeln!(output, " Self {{").unwrap();
|
||||
writeln!(output, " name: name.clone(),").unwrap();
|
||||
writeln!(
|
||||
output,
|
||||
" by: {} {{ client, name, _marker: std::marker::PhantomData }}",
|
||||
" pub fn new(client: Arc<BrkClientBase>, name: String) -> Self {{ let name: Arc<str> = name.into(); Self {{ name: name.clone(), by: {} {{ client, name, _marker: std::marker::PhantomData }} }} }}",
|
||||
by_name
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(output, " }}").unwrap();
|
||||
writeln!(output, " }}").unwrap();
|
||||
writeln!(output).unwrap();
|
||||
writeln!(output, " /// Get the metric name.").unwrap();
|
||||
writeln!(output, " pub fn name(&self) -> &str {{").unwrap();
|
||||
writeln!(output, " &self.name").unwrap();
|
||||
writeln!(output, " }}").unwrap();
|
||||
writeln!(output, " pub fn name(&self) -> &str {{ &self.name }}").unwrap();
|
||||
writeln!(output, "}}\n").unwrap();
|
||||
|
||||
// Implement AnyMetricPattern trait
|
||||
writeln!(
|
||||
output,
|
||||
"impl<T> AnyMetricPattern for {}<T> {{",
|
||||
pattern.name
|
||||
"impl<T> AnyMetricPattern for {}<T> {{ fn name(&self) -> &str {{ &self.name }} fn indexes(&self) -> &'static [Index] {{ {} }} }}",
|
||||
pattern.name, idx_const
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(output, " fn name(&self) -> &str {{").unwrap();
|
||||
writeln!(output, " &self.name").unwrap();
|
||||
writeln!(output, " }}").unwrap();
|
||||
writeln!(output).unwrap();
|
||||
writeln!(output, " fn indexes(&self) -> &'static [Index] {{").unwrap();
|
||||
writeln!(output, " &[").unwrap();
|
||||
for index in &pattern.indexes {
|
||||
writeln!(output, " Index::{},", index).unwrap();
|
||||
}
|
||||
writeln!(output, " ]").unwrap();
|
||||
writeln!(output, " }}").unwrap();
|
||||
writeln!(output, "}}\n").unwrap();
|
||||
|
||||
// Implement MetricPattern<T> trait
|
||||
writeln!(
|
||||
output,
|
||||
"impl<T: DeserializeOwned> MetricPattern<T> for {}<T> {{",
|
||||
pattern.name
|
||||
"impl<T: DeserializeOwned> MetricPattern<T> for {}<T> {{ fn get(&self, index: Index) -> Option<MetricEndpointBuilder<T>> {{ {}.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) }} }}\n",
|
||||
pattern.name, idx_const
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(
|
||||
output,
|
||||
" fn get(&self, index: Index) -> Option<MetricEndpointBuilder<T>> {{"
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(output, " match index {{").unwrap();
|
||||
for index in &pattern.indexes {
|
||||
let method_name = index_to_field_name(index);
|
||||
writeln!(
|
||||
output,
|
||||
" Index::{} => Some(self.by.{}()),",
|
||||
index, method_name
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
writeln!(output, " _ => None,").unwrap();
|
||||
writeln!(output, " }}").unwrap();
|
||||
writeln!(output, " }}").unwrap();
|
||||
writeln!(output, "}}\n").unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+609
-1998
File diff suppressed because it is too large
Load Diff
+553
-1469
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user