mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-18 22:48:10 -07:00
98 lines
3.1 KiB
Rust
98 lines
3.1 KiB
Rust
//! Rust language syntax implementation.
|
|
|
|
use crate::{GenericSyntax, LanguageSyntax, escape_rust_keyword, to_snake_case};
|
|
|
|
/// Rust-specific code generation syntax.
|
|
pub struct RustSyntax;
|
|
|
|
/// Escape braces in a template string for use in `format!()`, preserving `{disc}`.
|
|
fn escape_rust_format(template: &str) -> String {
|
|
template
|
|
.replace('{', "{{")
|
|
.replace('}', "}}")
|
|
.replace("{{disc}}", "{disc}")
|
|
}
|
|
|
|
impl LanguageSyntax for RustSyntax {
|
|
fn field_name(&self, name: &str) -> String {
|
|
escape_rust_keyword(&to_snake_case(name))
|
|
}
|
|
|
|
fn path_expr(&self, base_var: &str, suffix: &str) -> String {
|
|
format!("format!(\"{{{}}}{}\")", base_var, suffix)
|
|
}
|
|
|
|
fn suffix_expr(&self, acc_var: &str, relative: &str) -> String {
|
|
if relative.is_empty() {
|
|
self.owned_expr(acc_var)
|
|
} else {
|
|
format!("_m(&{}, \"{}\")", acc_var, relative)
|
|
}
|
|
}
|
|
|
|
fn owned_expr(&self, var: &str) -> String {
|
|
format!("{}.clone()", var)
|
|
}
|
|
|
|
fn prefix_expr(&self, prefix: &str, acc_var: &str) -> String {
|
|
if prefix.is_empty() {
|
|
self.owned_expr(acc_var)
|
|
} else {
|
|
let prefix_base = prefix.trim_end_matches('_');
|
|
format!("_p(\"{}\", &{})", prefix_base, acc_var)
|
|
}
|
|
}
|
|
|
|
fn constructor(&self, type_name: &str, path_expr: &str) -> String {
|
|
format!("{}::new(client.clone(), {})", type_name, path_expr)
|
|
}
|
|
|
|
fn field_init(&self, indent: &str, name: &str, _type_ann: &str, value: &str) -> String {
|
|
// Rust struct initialization; type is in struct definition, not in init
|
|
format!("{}{}: {},", indent, name, value)
|
|
}
|
|
|
|
fn generic_syntax(&self) -> GenericSyntax {
|
|
GenericSyntax::RUST
|
|
}
|
|
|
|
fn string_literal(&self, value: &str) -> String {
|
|
format!("\"{}\".to_string()", value)
|
|
}
|
|
|
|
fn constructor_name(&self, type_name: &str) -> String {
|
|
format!("{}::new", type_name)
|
|
}
|
|
|
|
fn disc_arg_expr(&self, template: &str) -> String {
|
|
if template == "{disc}" {
|
|
"disc.clone()".to_string()
|
|
} else if template.is_empty() {
|
|
"String::new()".to_string()
|
|
} else if !template.contains("{disc}") {
|
|
format!("\"{}\".to_string()", template)
|
|
} else if template.ends_with("{disc}") {
|
|
let static_part = template.trim_end_matches("{disc}").trim_end_matches('_');
|
|
format!("_m(\"{}\", &disc)", static_part)
|
|
} else {
|
|
format!("format!(\"{}\")", escape_rust_format(template))
|
|
}
|
|
}
|
|
|
|
fn template_expr(&self, acc_var: &str, template: &str) -> String {
|
|
if template == "{disc}" {
|
|
format!("_m(&{}, &disc)", acc_var)
|
|
} else if template.is_empty() {
|
|
acc_var.to_string()
|
|
} else if !template.contains("{disc}") {
|
|
format!("_m(&{}, \"{}\")", acc_var, template)
|
|
} else {
|
|
format!(
|
|
"_m(&{}, &format!(\"{}\", disc=disc))",
|
|
acc_var,
|
|
escape_rust_format(template)
|
|
)
|
|
}
|
|
}
|
|
}
|