use super::expr::*;
use crate::ffi::{
Expr as FfiExpr,
ListExprElement as FfiListExprElement,
StructExprField as FfiStructExprField,
MapExprEntry as FfiMapExprEntry,
MacroExprFactory as FfiMacroExprFactory,
};
use std::pin::Pin;
pub struct MacroExprFactory<'a>(pub(crate) std::sync::RwLock<Pin<&'a mut FfiMacroExprFactory>>);
impl<'a> MacroExprFactory<'a> {
pub(crate) fn new(ffi_macro_expr_factory: Pin<&'a mut FfiMacroExprFactory>) -> Self {
Self(std::sync::RwLock::new(ffi_macro_expr_factory))
}
pub fn copy_expr(&self, expr: &Expr) -> Expr {
let ffi_expr: cxx::UniquePtr<FfiExpr> = expr.into();
let ffi_copied = self.0.write().expect("Failed to write to RwLock")
.as_mut().copy(&ffi_expr);
ffi_copied.into()
}
pub fn copy_list_expr_element(&self, list_expr_element: &ListExprElement) -> ListExprElement {
let ffi_list_expr_element: cxx::UniquePtr<FfiListExprElement> = list_expr_element.into();
let ffi_copied = self.0.write().expect("Failed to write to RwLock")
.as_mut().copy_list_element(&ffi_list_expr_element);
ffi_copied.into()
}
pub fn copy_struct_expr_field(&self, struct_expr_field: &StructExprField) -> StructExprField {
let ffi_struct_expr_field: cxx::UniquePtr<FfiStructExprField> = struct_expr_field.into();
let ffi_copied = self.0.write().expect("Failed to write to RwLock")
.as_mut().copy_struct_field(&ffi_struct_expr_field);
ffi_copied.into()
}
pub fn copy_map_expr_entry(&self, map_expr_entry: &MapExprEntry) -> MapExprEntry {
let ffi_map_expr_entry: cxx::UniquePtr<FfiMapExprEntry> = map_expr_entry.into();
let ffi_copied = self.0.write().expect("Failed to write to RwLock")
.as_mut().copy_map_entry(&ffi_map_expr_entry);
ffi_copied.into()
}
pub fn new_unspecified(&mut self) -> Expr {
let ffi_unspecified = self.0.write().expect("Failed to write to RwLock")
.as_mut().new_unspecified();
ffi_unspecified.into()
}
pub fn new_const<T>(&self, value: T) -> Expr
where
T: crate::IntoConstant,
{
let mut expr = Expr::from(self.0.write().expect("Failed to write to RwLock")
.as_mut().new_unspecified());
expr.set_kind(ExprKind::Constant(value.into_constant()));
expr
}
pub fn new_ident(&self, name: &str) -> Expr {
let ffi_ident = self.0.write().expect("Failed to write to RwLock")
.as_mut().new_ident(name.into());
ffi_ident.into()
}
pub fn accu_var_name(&self) -> String {
let mut guard = self.0.write().expect("Failed to write to RwLock");
guard.as_mut().accu_var_name().to_string_lossy().to_string()
}
pub fn new_accu_ident(&self) -> Expr {
let ffi_accu_ident = self.0.write().expect("Failed to write to RwLock")
.as_mut().new_accu_ident();
ffi_accu_ident.into()
}
pub fn new_select(&self, operand: &Expr, field: &str) -> Expr {
let ffi_select = self.0.write().expect("Failed to write to RwLock")
.as_mut().new_select(operand.into(), field.into());
ffi_select.into()
}
pub fn new_presence_test(&self, operand: &Expr, field: &str) -> Expr {
let ffi_presence_test = self.0.write().expect("Failed to write to RwLock")
.as_mut().new_presence_test(operand.into(), field.into());
ffi_presence_test.into()
}
pub fn new_call(&self, function: &str, args: &[Expr]) -> Expr {
let mut ffi_args = cxx::CxxVector::new();
for arg in args {
use crate::ffi::CxxVectorExt;
ffi_args.pin_mut().push_unique(arg.into());
}
let ffi_call = self.0.write().expect("Failed to write to RwLock")
.as_mut().new_call(function.into(), ffi_args);
ffi_call.into()
}
pub fn new_member_call(&self, function: &str, target: &Expr, args: &[Expr]) -> Expr {
let mut ffi_args = cxx::CxxVector::new();
for arg in args {
use crate::ffi::CxxVectorExt;
ffi_args.pin_mut().push_unique(arg.into());
}
let ffi_member_call = self.0.write().expect("Failed to write to RwLock")
.as_mut()
.new_member_call(function.into(), target.into(), ffi_args);
ffi_member_call.into()
}
pub fn new_list_element(&self, expr: &Expr, optional: bool) -> ListExprElement {
let ffi_list_element = self.0.write().expect("Failed to write to RwLock")
.as_mut().new_list_element(expr.into(), optional);
ffi_list_element.into()
}
pub fn new_list(&self, elements: &[ListExprElement]) -> Expr {
let mut ffi_elements = cxx::CxxVector::new();
for element in elements {
use crate::ffi::CxxVectorExt;
ffi_elements.pin_mut().push_unique(element.into());
}
let ffi_list = self.0.write().expect("Failed to write to RwLock")
.as_mut().new_list(ffi_elements);
ffi_list.into()
}
pub fn new_struct_field(&self, name: &str, value: &Expr, optional: bool) -> StructExprField {
let ffi_struct_field = self.0.write().expect("Failed to write to RwLock")
.as_mut()
.new_struct_field(name.into(), value.into(), optional);
ffi_struct_field.into()
}
pub fn new_struct(&self, name: &str, fields: &[StructExprField]) -> Expr {
let mut ffi_fields = cxx::CxxVector::new();
for field in fields {
use crate::ffi::CxxVectorExt;
ffi_fields.pin_mut().push_unique(field.into());
}
let ffi_struct = self.0.write().expect("Failed to write to RwLock")
.as_mut().new_struct(name.into(), ffi_fields);
ffi_struct.into()
}
pub fn new_map_entry(&self, key: &Expr, value: &Expr, optional: bool) -> MapExprEntry {
let ffi_map_entry = self.0.write().expect("Failed to write to RwLock")
.as_mut()
.new_map_entry(key.into(), value.into(), optional);
ffi_map_entry.into()
}
pub fn new_map(&self, entries: &[MapExprEntry]) -> Expr {
let mut ffi_entries = cxx::CxxVector::new();
for entry in entries {
use crate::ffi::CxxVectorExt;
ffi_entries.pin_mut().push_unique(entry.into());
}
let ffi_map = self.0.write().expect("Failed to write to RwLock")
.as_mut().new_map(ffi_entries);
ffi_map.into()
}
pub fn new_comprehension(
&self,
iter_var: &str,
iter_range: &Expr,
accu_var: &str,
accu_init: &Expr,
loop_condition: &Expr,
loop_step: &Expr,
result: &Expr) -> Expr {
let ffi_iter_var = iter_var.into();
let ffi_iter_range = iter_range.into();
let ffi_accu_var = accu_var.into();
let ffi_accu_init = accu_init.into();
let ffi_loop_condition = loop_condition.into();
let ffi_loop_step = loop_step.into();
let ffi_result = result.into();
let ffi_comprehension = self.0.write().expect("Failed to write to RwLock")
.as_mut()
.new_comprehension(
ffi_iter_var,
ffi_iter_range,
ffi_accu_var,
ffi_accu_init,
ffi_loop_condition,
ffi_loop_step,
ffi_result
);
ffi_comprehension.into()
}
pub fn new_comprehension2(
&self,
iter_var: &str,
iter_var2: &str,
iter_range: &Expr,
accu_var: &str,
accu_init: &Expr,
loop_condition: &Expr,
loop_step: &Expr,
result: &Expr) -> Expr {
let ffi_iter_var = iter_var.into();
let ffi_iter_var2 = iter_var2.into();
let ffi_iter_range = iter_range.into();
let ffi_accu_var = accu_var.into();
let ffi_accu_init = accu_init.into();
let ffi_loop_condition = loop_condition.into();
let ffi_loop_step = loop_step.into();
let ffi_result = result.into();
let ffi_comprehension = self.0.write().expect("Failed to write to RwLock")
.as_mut()
.new_comprehension2(
ffi_iter_var,
ffi_iter_var2,
ffi_iter_range,
ffi_accu_var,
ffi_accu_init,
ffi_loop_condition,
ffi_loop_step,
ffi_result
);
ffi_comprehension.into()
}
pub fn report_error(&self, message: &str) -> Expr {
let ffi_report_error = self.0.write().expect("Failed to write to RwLock")
.as_mut().report_error(message.into());
ffi_report_error.into()
}
pub fn report_error_at(&self, expr: &Expr, message: &str) -> Expr {
let ffi_expr: cxx::UniquePtr<FfiExpr> = expr.into();
let ffi_report_error = self.0.write().expect("Failed to write to RwLock")
.as_mut().report_error_at(&ffi_expr, message.into());
ffi_report_error.into()
}
}
impl std::fmt::Debug for MacroExprFactory<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "MacroExprFactory(..)")
}
}