mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-13 03:58:12 -07:00
global: snapshot
This commit is contained in:
@@ -12,7 +12,7 @@ use serde_json::Value;
|
||||
|
||||
use crate::{
|
||||
ClientMetadata, GenericSyntax, IndexSetPattern, JavaScriptSyntax, StructuralPattern, VERSION,
|
||||
generate_parameterized_field, generate_tree_path_field, to_camel_case,
|
||||
generate_parameterized_field, to_camel_case,
|
||||
};
|
||||
|
||||
/// Generate the base BrkClient class with HTTP functionality.
|
||||
@@ -186,7 +186,7 @@ function _endpoint(client, name, index) {{
|
||||
get(index) {{ return singleItemBuilder(index); }},
|
||||
slice(start, end) {{ return rangeBuilder(start, end); }},
|
||||
first(n) {{ return rangeBuilder(undefined, n); }},
|
||||
last(n) {{ return rangeBuilder(-n, undefined); }},
|
||||
last(n) {{ return n === 0 ? rangeBuilder(undefined, 0) : rangeBuilder(-n, undefined); }},
|
||||
skip(n) {{ return skippedBuilder(n); }},
|
||||
fetch(onUpdate) {{ return client.getJson(buildPath(), onUpdate); }},
|
||||
fetchCsv() {{ return client.getText(buildPath(undefined, undefined, 'csv')); }},
|
||||
@@ -220,7 +220,7 @@ class BrkClientBase {{
|
||||
const base = this.baseUrl.endsWith('/') ? this.baseUrl.slice(0, -1) : this.baseUrl;
|
||||
const url = `${{base}}${{path}}`;
|
||||
const res = await fetch(url, {{ signal: AbortSignal.timeout(this.timeout) }});
|
||||
if (!res.ok) throw new BrkError(`HTTP ${{res.status}}`, res.status);
|
||||
if (!res.ok) throw new BrkError(`HTTP ${{res.status}}: ${{url}}`, res.status);
|
||||
return res;
|
||||
}}
|
||||
|
||||
@@ -271,12 +271,20 @@ class BrkClientBase {{
|
||||
}}
|
||||
|
||||
/**
|
||||
* Build metric name with optional prefix.
|
||||
* Build metric name with suffix.
|
||||
* @param {{string}} acc - Accumulated prefix
|
||||
* @param {{string}} s - Metric suffix
|
||||
* @returns {{string}}
|
||||
*/
|
||||
const _m = (acc, s) => acc ? `${{acc}}_${{s}}` : s;
|
||||
const _m = (acc, s) => s ? (acc ? `${{acc}}_${{s}}` : s) : acc;
|
||||
|
||||
/**
|
||||
* Build metric name with prefix.
|
||||
* @param {{string}} prefix - Prefix to prepend
|
||||
* @param {{string}} acc - Accumulated name
|
||||
* @returns {{string}}
|
||||
*/
|
||||
const _p = (prefix, acc) => acc ? `${{prefix}}_${{acc}}` : prefix;
|
||||
|
||||
"#
|
||||
)
|
||||
@@ -470,8 +478,7 @@ pub fn generate_structural_patterns(
|
||||
writeln!(output, "// Reusable structural pattern factories\n").unwrap();
|
||||
|
||||
for pattern in patterns {
|
||||
let is_parameterizable = pattern.is_parameterizable();
|
||||
|
||||
// Generate typedef
|
||||
writeln!(output, "/**").unwrap();
|
||||
if pattern.is_generic {
|
||||
writeln!(output, " * @template T").unwrap();
|
||||
@@ -494,17 +501,14 @@ pub fn generate_structural_patterns(
|
||||
}
|
||||
writeln!(output, " */\n").unwrap();
|
||||
|
||||
// Generate factory function for ALL patterns
|
||||
writeln!(output, "/**").unwrap();
|
||||
writeln!(output, " * Create a {} pattern node", pattern.name).unwrap();
|
||||
if pattern.is_generic {
|
||||
writeln!(output, " * @template T").unwrap();
|
||||
}
|
||||
writeln!(output, " * @param {{BrkClientBase}} client").unwrap();
|
||||
if is_parameterizable {
|
||||
writeln!(output, " * @param {{string}} acc - Accumulated metric name").unwrap();
|
||||
} else {
|
||||
writeln!(output, " * @param {{string}} basePath").unwrap();
|
||||
}
|
||||
writeln!(output, " * @param {{string}} acc - Accumulated metric name").unwrap();
|
||||
let return_type = if pattern.is_generic {
|
||||
format!("{}<T>", pattern.name)
|
||||
} else {
|
||||
@@ -513,26 +517,12 @@ pub fn generate_structural_patterns(
|
||||
writeln!(output, " * @returns {{{}}}", return_type).unwrap();
|
||||
writeln!(output, " */").unwrap();
|
||||
|
||||
let param_name = if is_parameterizable {
|
||||
"acc"
|
||||
} else {
|
||||
"basePath"
|
||||
};
|
||||
writeln!(
|
||||
output,
|
||||
"function create{}(client, {}) {{",
|
||||
pattern.name, param_name
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(output, "function create{}(client, acc) {{", pattern.name).unwrap();
|
||||
writeln!(output, " return {{").unwrap();
|
||||
|
||||
let syntax = JavaScriptSyntax;
|
||||
for field in &pattern.fields {
|
||||
if is_parameterizable {
|
||||
generate_parameterized_field(output, &syntax, field, pattern, metadata, " ");
|
||||
} else {
|
||||
generate_tree_path_field(output, &syntax, field, metadata, " ");
|
||||
}
|
||||
generate_parameterized_field(output, &syntax, field, pattern, metadata, " ");
|
||||
}
|
||||
|
||||
writeln!(output, " }};").unwrap();
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
//! This module generates a JavaScript + JSDoc client for the BRK API.
|
||||
|
||||
mod api;
|
||||
mod client;
|
||||
mod tree;
|
||||
mod types;
|
||||
pub mod client;
|
||||
pub mod tree;
|
||||
pub mod types;
|
||||
|
||||
use std::{fmt::Write, fs, io, path::Path};
|
||||
|
||||
|
||||
@@ -175,10 +175,8 @@ fn generate_tree_initializer(
|
||||
TreeNode::Branch(grandchildren) => {
|
||||
let field_name = to_camel_case(child_name);
|
||||
let child_fields = get_node_fields(grandchildren, pattern_lookup);
|
||||
// Only use pattern factory if pattern is parameterizable
|
||||
let pattern_name = pattern_lookup
|
||||
.get(&child_fields)
|
||||
.filter(|name| metadata.is_parameterizable(name));
|
||||
// Use pattern factory if ANY pattern matches (not just parameterizable)
|
||||
let pattern_name = pattern_lookup.get(&child_fields);
|
||||
|
||||
let base_result = get_pattern_instance_base(child_node);
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ use serde::Serialize;
|
||||
|
||||
use crate::{
|
||||
ClientMetadata, IndexSetPattern, PythonSyntax, StructuralPattern, VERSION,
|
||||
generate_parameterized_field, generate_tree_path_field, index_to_field_name,
|
||||
generate_parameterized_field, index_to_field_name,
|
||||
};
|
||||
|
||||
/// Generate class-level constants for the BrkClient class.
|
||||
@@ -132,9 +132,15 @@ class BrkClientBase:
|
||||
|
||||
|
||||
def _m(acc: str, s: str) -> str:
|
||||
"""Build metric name with optional prefix."""
|
||||
"""Build metric name with suffix."""
|
||||
if not s: return acc
|
||||
return f"{{acc}}_{{s}}" if acc else s
|
||||
|
||||
|
||||
def _p(prefix: str, acc: str) -> str:
|
||||
"""Build metric name with prefix."""
|
||||
return f"{{prefix}}_{{acc}}" if acc else prefix
|
||||
|
||||
"#
|
||||
)
|
||||
.unwrap();
|
||||
@@ -309,9 +315,10 @@ class MetricEndpointBuilder(Generic[T]):
|
||||
|
||||
def tail(self, n: int = 10) -> RangeBuilder[T]:
|
||||
"""Get the last n items (pandas-style)."""
|
||||
start, end = (None, 0) if n == 0 else (-n, None)
|
||||
return RangeBuilder(_EndpointConfig(
|
||||
self._config.client, self._config.name, self._config.index,
|
||||
-n, None
|
||||
start, end
|
||||
))
|
||||
|
||||
def skip(self, n: int) -> SkippedBuilder[T]:
|
||||
@@ -467,9 +474,7 @@ pub fn generate_structural_patterns(
|
||||
writeln!(output, "# Reusable structural pattern classes\n").unwrap();
|
||||
|
||||
for pattern in patterns {
|
||||
let is_parameterizable = pattern.is_parameterizable();
|
||||
|
||||
// For generic patterns, inherit from Generic[T]
|
||||
// Generate class
|
||||
if pattern.is_generic {
|
||||
writeln!(output, "class {}(Generic[T]):", pattern.name).unwrap();
|
||||
} else {
|
||||
@@ -481,33 +486,20 @@ pub fn generate_structural_patterns(
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(output, " ").unwrap();
|
||||
|
||||
if is_parameterizable {
|
||||
writeln!(
|
||||
output,
|
||||
" def __init__(self, client: BrkClientBase, acc: str):"
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(
|
||||
output,
|
||||
" \"\"\"Create pattern node with accumulated metric name.\"\"\""
|
||||
)
|
||||
.unwrap();
|
||||
} else {
|
||||
writeln!(
|
||||
output,
|
||||
" def __init__(self, client: BrkClientBase, base_path: str):"
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
writeln!(
|
||||
output,
|
||||
" def __init__(self, client: BrkClientBase, acc: str):"
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(
|
||||
output,
|
||||
" \"\"\"Create pattern node with accumulated metric name.\"\"\""
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let syntax = PythonSyntax;
|
||||
for field in &pattern.fields {
|
||||
if is_parameterizable {
|
||||
generate_parameterized_field(output, &syntax, field, pattern, metadata, " ");
|
||||
} else {
|
||||
generate_tree_path_field(output, &syntax, field, metadata, " ");
|
||||
}
|
||||
generate_parameterized_field(output, &syntax, field, pattern, metadata, " ");
|
||||
}
|
||||
|
||||
writeln!(output).unwrap();
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
//!
|
||||
//! This module generates a Python client with type hints for the BRK API.
|
||||
|
||||
mod api;
|
||||
mod client;
|
||||
mod tree;
|
||||
mod types;
|
||||
pub mod api;
|
||||
pub mod client;
|
||||
pub mod tree;
|
||||
pub mod types;
|
||||
|
||||
use std::{fmt::Write, fs, io, path::Path};
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::fmt::Write;
|
||||
|
||||
use crate::{
|
||||
ClientMetadata, GenericSyntax, IndexSetPattern, RustSyntax, StructuralPattern,
|
||||
generate_parameterized_field, generate_tree_path_field, index_to_field_name, to_snake_case,
|
||||
generate_parameterized_field, index_to_field_name, to_snake_case,
|
||||
};
|
||||
|
||||
/// Generate import statements.
|
||||
@@ -116,10 +116,18 @@ impl BrkClientBase {{
|
||||
}}
|
||||
}}
|
||||
|
||||
/// Build metric name with optional prefix.
|
||||
/// Build metric name with suffix.
|
||||
#[inline]
|
||||
fn _m(acc: &str, s: &str) -> String {{
|
||||
if acc.is_empty() {{ s.to_string() }} else {{ format!("{{acc}}_{{s}}") }}
|
||||
if s.is_empty() {{ acc.to_string() }}
|
||||
else if acc.is_empty() {{ s.to_string() }}
|
||||
else {{ format!("{{acc}}_{{s}}") }}
|
||||
}}
|
||||
|
||||
/// Build metric name with prefix.
|
||||
#[inline]
|
||||
fn _p(prefix: &str, acc: &str) -> String {{
|
||||
if acc.is_empty() {{ prefix.to_string() }} else {{ format!("{{prefix}}_{{acc}}") }}
|
||||
}}
|
||||
|
||||
"#
|
||||
@@ -265,7 +273,11 @@ impl<T: DeserializeOwned> MetricEndpointBuilder<T> {{
|
||||
|
||||
/// Take the last n items.
|
||||
pub fn last(mut self, n: usize) -> RangeBuilder<T> {{
|
||||
self.config.start = Some(-(n as i64));
|
||||
if n == 0 {{
|
||||
self.config.end = Some(0);
|
||||
}} else {{
|
||||
self.config.start = Some(-(n as i64));
|
||||
}}
|
||||
RangeBuilder {{ config: self.config, _marker: std::marker::PhantomData }}
|
||||
}}
|
||||
|
||||
@@ -399,7 +411,6 @@ pub fn generate_index_accessors(output: &mut String, patterns: &[IndexSetPattern
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(output, "pub struct {}<T> {{", pattern.name).unwrap();
|
||||
writeln!(output, " client: Arc<BrkClientBase>,").unwrap();
|
||||
writeln!(output, " name: Arc<str>,").unwrap();
|
||||
writeln!(output, " pub by: {}<T>,", by_name).unwrap();
|
||||
writeln!(output, "}}\n").unwrap();
|
||||
@@ -413,13 +424,8 @@ pub fn generate_index_accessors(output: &mut String, patterns: &[IndexSetPattern
|
||||
.unwrap();
|
||||
writeln!(output, " let name: Arc<str> = name.into();").unwrap();
|
||||
writeln!(output, " Self {{").unwrap();
|
||||
writeln!(output, " client: client.clone(),").unwrap();
|
||||
writeln!(output, " name: name.clone(),").unwrap();
|
||||
writeln!(output, " by: {} {{", by_name).unwrap();
|
||||
writeln!(output, " client,").unwrap();
|
||||
writeln!(output, " name,").unwrap();
|
||||
writeln!(output, " _marker: std::marker::PhantomData,").unwrap();
|
||||
writeln!(output, " }}").unwrap();
|
||||
writeln!(output, " by: {} {{ client, name, _marker: std::marker::PhantomData }}", by_name).unwrap();
|
||||
writeln!(output, " }}").unwrap();
|
||||
writeln!(output, " }}").unwrap();
|
||||
writeln!(output).unwrap();
|
||||
@@ -472,9 +478,9 @@ pub fn generate_pattern_structs(
|
||||
writeln!(output, "// Reusable pattern structs\n").unwrap();
|
||||
|
||||
for pattern in patterns {
|
||||
let is_parameterizable = pattern.is_parameterizable();
|
||||
let generic_params = if pattern.is_generic { "<T>" } else { "" };
|
||||
|
||||
// Generate struct definition
|
||||
writeln!(output, "/// Pattern struct for repeated tree structure.").unwrap();
|
||||
writeln!(output, "pub struct {}{} {{", pattern.name, generic_params).unwrap();
|
||||
|
||||
@@ -487,7 +493,7 @@ pub fn generate_pattern_structs(
|
||||
|
||||
writeln!(output, "}}\n").unwrap();
|
||||
|
||||
// Generate impl block with constructor
|
||||
// Generate impl block with constructor for ALL patterns
|
||||
let impl_generic = if pattern.is_generic {
|
||||
"<T: DeserializeOwned>"
|
||||
} else {
|
||||
@@ -500,33 +506,21 @@ pub fn generate_pattern_structs(
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if is_parameterizable {
|
||||
writeln!(
|
||||
output,
|
||||
" /// Create a new pattern node with accumulated metric name."
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(
|
||||
output,
|
||||
" pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {{"
|
||||
)
|
||||
.unwrap();
|
||||
} else {
|
||||
writeln!(
|
||||
output,
|
||||
" pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {{"
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
writeln!(
|
||||
output,
|
||||
" /// Create a new pattern node with accumulated metric name."
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(
|
||||
output,
|
||||
" pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {{"
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(output, " Self {{").unwrap();
|
||||
|
||||
let syntax = RustSyntax;
|
||||
for field in &pattern.fields {
|
||||
if is_parameterizable {
|
||||
generate_parameterized_field(output, &syntax, field, pattern, metadata, " ");
|
||||
} else {
|
||||
generate_tree_path_field(output, &syntax, field, metadata, " ");
|
||||
}
|
||||
generate_parameterized_field(output, &syntax, field, pattern, metadata, " ");
|
||||
}
|
||||
|
||||
writeln!(output, " }}").unwrap();
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
//!
|
||||
//! This module generates a Rust client with full type safety for the BRK API.
|
||||
|
||||
mod api;
|
||||
mod client;
|
||||
mod tree;
|
||||
pub mod api;
|
||||
pub mod client;
|
||||
pub mod tree;
|
||||
mod types;
|
||||
|
||||
use std::{fmt::Write, fs, io, path::Path};
|
||||
|
||||
@@ -86,7 +86,7 @@ fn generate_tree_node(
|
||||
);
|
||||
}
|
||||
} else if child.should_inline {
|
||||
// Inline struct
|
||||
// Inline struct type - only for nodes that don't match any pattern
|
||||
let path_expr = syntax.path_expr("base_path", &format!("_{}", child.name));
|
||||
writeln!(
|
||||
output,
|
||||
@@ -95,7 +95,9 @@ fn generate_tree_node(
|
||||
)
|
||||
.unwrap();
|
||||
} else {
|
||||
// Use pattern constructor
|
||||
// Pattern type - use ::new() constructor
|
||||
// All patterns have ::new(), parameterizable ones use detected mode,
|
||||
// non-parameterizable ones use field name fallback
|
||||
generate_tree_node_field(
|
||||
output,
|
||||
&syntax,
|
||||
|
||||
Reference in New Issue
Block a user