use crate::Constant;
#[derive(Debug, Default)]
pub struct Expr {
id: i64,
kind: Option<Box<ExprKind>>,
}
impl std::ops::Deref for Expr {
type Target = ExprKind;
fn deref(&self) -> &Self::Target {
self.kind.as_ref().expect("Expr has no kind set")
}
}
impl std::ops::DerefMut for Expr {
fn deref_mut(&mut self) -> &mut Self::Target {
self.kind.as_mut().expect("Expr has no kind set")
}
}
impl Expr {
pub fn id(&self) -> i64 {
self.id
}
pub fn set_id(&mut self, id: i64) {
self.id = id;
}
pub fn kind(&self) -> Option<&ExprKind> {
self.kind.as_ref()
.map(|k| k.as_ref())
}
pub fn set_kind(&mut self, kind: ExprKind) {
self.kind = Some(Box::new(kind));
}
pub fn clear_kind(&mut self) {
self.kind = None;
}
}
#[derive(Debug)]
pub enum ExprKind {
Constant(Constant),
Ident(IdentExpr),
Select(SelectExpr),
Call(CallExpr),
List(ListExpr),
Struct(StructExpr),
Map(MapExpr),
Comprehension(ComprehensionExpr),
}
impl ExprKind {
pub fn is_constant(&self) -> bool {
matches!(self, ExprKind::Constant(_))
}
pub fn is_ident(&self) -> bool {
matches!(self, ExprKind::Ident(_))
}
pub fn is_select(&self) -> bool {
matches!(self, ExprKind::Select(_))
}
pub fn is_call(&self) -> bool {
matches!(self, ExprKind::Call(_))
}
pub fn is_list(&self) -> bool {
matches!(self, ExprKind::List(_))
}
pub fn is_struct(&self) -> bool {
matches!(self, ExprKind::Struct(_))
}
pub fn is_map(&self) -> bool {
matches!(self, ExprKind::Map(_))
}
pub fn is_comprehension(&self) -> bool {
matches!(self, ExprKind::Comprehension(_))
}
pub fn as_constant(&self) -> Option<&Constant> {
if let ExprKind::Constant(c) = self {
Some(c)
} else {
None
}
}
pub fn as_ident(&self) -> Option<&IdentExpr> {
if let ExprKind::Ident(i) = self {
Some(i)
} else {
None
}
}
pub fn as_select(&self) -> Option<&SelectExpr> {
if let ExprKind::Select(s) = self {
Some(s)
} else {
None
}
}
pub fn as_call(&self) -> Option<&CallExpr> {
if let ExprKind::Call(c) = self {
Some(c)
} else {
None
}
}
pub fn as_list(&self) -> Option<&ListExpr> {
if let ExprKind::List(l) = self {
Some(l)
} else {
None
}
}
pub fn as_struct(&self) -> Option<&StructExpr> {
if let ExprKind::Struct(s) = self {
Some(s)
} else {
None
}
}
pub fn as_map(&self) -> Option<&MapExpr> {
if let ExprKind::Map(m) = self {
Some(m)
} else {
None
}
}
pub fn as_comprehension(&self) -> Option<&ComprehensionExpr> {
if let ExprKind::Comprehension(c) = self {
Some(c)
} else {
None
}
}
pub fn as_constant_mut(&mut self) -> Option<&mut Constant> {
if let ExprKind::Constant(c) = self {
Some(c)
} else {
None
}
}
pub fn as_ident_mut(&mut self) -> Option<&mut IdentExpr> {
if let ExprKind::Ident(i) = self {
Some(i)
} else {
None
}
}
pub fn as_select_mut(&mut self) -> Option<&mut SelectExpr> {
if let ExprKind::Select(s) = self {
Some(s)
} else {
None
}
}
pub fn as_call_mut(&mut self) -> Option<&mut CallExpr> {
if let ExprKind::Call(c) = self {
Some(c)
} else {
None
}
}
pub fn as_list_mut(&mut self) -> Option<&mut ListExpr> {
if let ExprKind::List(l) = self {
Some(l)
} else {
None
}
}
pub fn as_struct_mut(&mut self) -> Option<&mut StructExpr> {
if let ExprKind::Struct(s) = self {
Some(s)
} else {
None
}
}
pub fn as_map_mut(&mut self) -> Option<&mut MapExpr> {
if let ExprKind::Map(m) = self {
Some(m)
} else {
None
}
}
pub fn as_comprehension_mut(&mut self) -> Option<&mut ComprehensionExpr> {
if let ExprKind::Comprehension(c) = self {
Some(c)
} else {
None
}
}
}
#[derive(Debug)]
pub struct IdentExpr {
pub name: String,
}
#[derive(Debug)]
pub struct SelectExpr {
pub operand: Expr,
pub field: String,
pub test_only: bool,
}
#[derive(Debug)]
pub struct CallExpr {
pub function: String,
pub target: Expr,
pub args: Vec<Expr>,
}
#[derive(Debug)]
pub struct ListExprElement {
pub expr: Expr,
pub optional: bool,
}
#[derive(Debug)]
pub struct ListExpr {
pub elements: Vec<ListExprElement>,
}
#[derive(Debug)]
pub struct StructExprField {
pub id: i64,
pub name: String,
pub value: Expr,
pub optional: bool,
}
#[derive(Debug)]
pub struct StructExpr {
pub name: String,
pub fields: Vec<StructExprField>,
}
#[derive(Debug)]
pub struct MapExprEntry {
pub id: i64,
pub key: Expr,
pub value: Expr,
pub optional: bool,
}
#[derive(Debug)]
pub struct MapExpr {
pub entries: Vec<MapExprEntry>,
}
#[derive(Debug)]
pub struct ComprehensionExpr {
pub iter_var: String,
pub iter_var2: String,
pub iter_range: Expr,
pub accu_var: String,
pub accu_init: Expr,
pub loop_condition: Expr,
pub loop_step: Expr,
pub result: Expr,
}
impl From<&Expr> for cxx::UniquePtr<crate::ffi::Expr> {
fn from(value: &Expr) -> Self {
use crate::ffi::Expr as FfiExpr;
use crate::ffi::Constant as FfiConstant;
use crate::ffi::CxxVectorExt;
let mut ffi_expr = FfiExpr::new();
ffi_expr.pin_mut().set_id(value.id());
match value.kind() {
None => {}
Some(ExprKind::Constant(constant)) => {
let ffi_constant: cxx::UniquePtr<FfiConstant> = constant.into();
ffi_expr.pin_mut()
.set_const_expr(ffi_constant);
}
Some(ExprKind::Ident(ident)) => {
let mut ident_expr = ffi_expr.pin_mut().ident_expr_mut();
ident_expr.as_mut().set_name(ident.name.as_str().into());
}
Some(ExprKind::Select(select)) => {
let mut select_expr = ffi_expr.pin_mut().select_expr_mut();
select_expr.as_mut().set_operand((&select.operand).into());
select_expr.as_mut().set_field(select.field.as_str().into());
select_expr.as_mut().set_test_only(select.test_only);
}
Some(ExprKind::Call(call)) => {
let mut call_expr = ffi_expr.pin_mut().call_expr_mut();
call_expr.as_mut().set_function(call.function.as_str().into());
call_expr.as_mut().set_target((&call.target).into());
let mut args = call_expr.as_mut().args_mut();
for arg in &call.args {
args.as_mut().push_unique(arg.into());
}
}
Some(ExprKind::List(list)) => {
let mut list_expr = ffi_expr.pin_mut().list_expr_mut();
let mut elements = list_expr.as_mut().elements_mut();
for element in &list.elements {
elements.as_mut().push_unique(element.into());
}
}
Some(ExprKind::Struct(struct_)) => {
let mut struct_expr = ffi_expr.pin_mut().struct_expr_mut();
let mut fields = struct_expr.as_mut().fields_mut();
for field in &struct_.fields {
fields.as_mut().push_unique(field.into());
}
}
Some(ExprKind::Map(map)) => {
let mut map_expr = ffi_expr.pin_mut().map_expr_mut();
let mut entries = map_expr.as_mut().entries_mut();
for entry in &map.entries {
entries.as_mut().push_unique(entry.into());
}
}
Some(ExprKind::Comprehension(comprehension)) => {
let mut comprehension_expr = ffi_expr.pin_mut().comprehension_expr_mut();
comprehension_expr.as_mut().set_iter_var(comprehension.iter_var.as_str().into());
comprehension_expr.as_mut().set_iter_var2(comprehension.iter_var2.as_str().into());
comprehension_expr.as_mut().set_iter_range((&comprehension.iter_range).into());
comprehension_expr.as_mut().set_accu_var(comprehension.accu_var.as_str().into());
comprehension_expr.as_mut().set_accu_init((&comprehension.accu_init).into());
comprehension_expr.as_mut().set_loop_condition((&comprehension.loop_condition).into());
comprehension_expr.as_mut().set_loop_step((&comprehension.loop_step).into());
comprehension_expr.as_mut().set_result((&comprehension.result).into());
}
}
ffi_expr
}
}
impl From<Expr> for cxx::UniquePtr<crate::ffi::Expr> {
fn from(value: Expr) -> Self {
Self::from(&value)
}
}
impl From<&crate::ffi::Expr> for Expr {
fn from(value: &crate::ffi::Expr) -> Self {
use crate::ffi::ExprKindCase as FfiExprKindCase;
let mut expr = Expr::default();
expr.set_id(value.id());
let kind = match value.kind_case() {
FfiExprKindCase::Unspecified => None,
FfiExprKindCase::Constant => Some(ExprKind::Constant(Constant::from(value.const_expr()))),
FfiExprKindCase::Ident => Some(ExprKind::Ident(IdentExpr::from(value.ident_expr()))),
FfiExprKindCase::Select => Some(ExprKind::Select(SelectExpr::from(value.select_expr()))),
FfiExprKindCase::Call => Some(ExprKind::Call(CallExpr::from(value.call_expr()))),
FfiExprKindCase::List => Some(ExprKind::List(ListExpr::from(value.list_expr()))),
FfiExprKindCase::Struct => Some(ExprKind::Struct(StructExpr::from(value.struct_expr()))),
FfiExprKindCase::Map => Some(ExprKind::Map(MapExpr::from(value.map_expr()))),
FfiExprKindCase::Comprehension => Some(ExprKind::Comprehension(ComprehensionExpr::from(value.comprehension_expr()))),
};
if let Some(kind) = kind {
expr.set_kind(kind);
}
expr
}
}
impl From<cxx::UniquePtr<crate::ffi::Expr>> for Expr {
fn from(value: cxx::UniquePtr<crate::ffi::Expr>) -> Self {
Self::from(&*value)
}
}
impl From<&crate::ffi::IdentExpr> for IdentExpr {
fn from(value: &crate::ffi::IdentExpr) -> Self {
IdentExpr {
name: value.name().to_string(),
}
}
}
impl From<cxx::UniquePtr<crate::ffi::IdentExpr>> for IdentExpr {
fn from(value: cxx::UniquePtr<crate::ffi::IdentExpr>) -> Self {
Self::from(&*value)
}
}
impl From<&crate::ffi::SelectExpr> for SelectExpr {
fn from(value: &crate::ffi::SelectExpr) -> Self {
SelectExpr {
operand: Expr::from(value.operand()),
field: value.field().to_string(),
test_only: value.test_only(),
}
}
}
impl From<cxx::UniquePtr<crate::ffi::SelectExpr>> for SelectExpr {
fn from(value: cxx::UniquePtr<crate::ffi::SelectExpr>) -> Self {
Self::from(&*value)
}
}
impl From<&crate::ffi::CallExpr> for CallExpr {
fn from(value: &crate::ffi::CallExpr) -> Self {
CallExpr {
function: value.function().to_string(),
target: Expr::from(value.target()),
args: value.args()
.into_iter()
.map(|arg| Expr::from(arg))
.collect(),
}
}
}
impl From<cxx::UniquePtr<crate::ffi::CallExpr>> for CallExpr {
fn from(value: cxx::UniquePtr<crate::ffi::CallExpr>) -> Self {
Self::from(&*value)
}
}
impl From<&crate::ffi::ListExpr> for ListExpr {
fn from(value: &crate::ffi::ListExpr) -> Self {
ListExpr {
elements: value.elements()
.into_iter()
.map(|element| ListExprElement::from(element))
.collect(),
}
}
}
impl From<cxx::UniquePtr<crate::ffi::ListExpr>> for ListExpr {
fn from(value: cxx::UniquePtr<crate::ffi::ListExpr>) -> Self {
Self::from(&*value)
}
}
impl From<&crate::ffi::StructExpr> for StructExpr {
fn from(value: &crate::ffi::StructExpr) -> Self {
StructExpr {
name: value.name().to_string(),
fields: value.fields()
.into_iter()
.map(|field| StructExprField::from(field))
.collect(),
}
}
}
impl From<cxx::UniquePtr<crate::ffi::StructExpr>> for StructExpr {
fn from(value: cxx::UniquePtr<crate::ffi::StructExpr>) -> Self {
Self::from(&*value)
}
}
impl From<&crate::ffi::MapExpr> for MapExpr {
fn from(value: &crate::ffi::MapExpr) -> Self {
MapExpr {
entries: value.entries()
.into_iter()
.map(|entry| MapExprEntry::from(entry))
.collect(),
}
}
}
impl From<cxx::UniquePtr<crate::ffi::MapExpr>> for MapExpr {
fn from(value: cxx::UniquePtr<crate::ffi::MapExpr>) -> Self {
Self::from(&*value)
}
}
impl From<&crate::ffi::ComprehensionExpr> for ComprehensionExpr {
fn from(value: &crate::ffi::ComprehensionExpr) -> Self {
ComprehensionExpr {
iter_var: value.iter_var().to_string(),
iter_var2: value.iter_var2().to_string(),
iter_range: Expr::from(value.iter_range()),
accu_var: value.accu_var().to_string(),
accu_init: Expr::from(value.accu_init()),
loop_condition: Expr::from(value.loop_condition()),
loop_step: Expr::from(value.loop_step()),
result: Expr::from(value.result()),
}
}
}
impl From<cxx::UniquePtr<crate::ffi::ComprehensionExpr>> for ComprehensionExpr {
fn from(value: cxx::UniquePtr<crate::ffi::ComprehensionExpr>) -> Self {
Self::from(&*value)
}
}
impl From<&ListExprElement> for cxx::UniquePtr<crate::ffi::ListExprElement> {
fn from(value: &ListExprElement) -> Self {
use crate::ffi::ListExprElement as FfiListExprElement;
let mut ffi_element = FfiListExprElement::new();
ffi_element.pin_mut().set_expr((&value.expr).into());
ffi_element.pin_mut().set_optional(value.optional);
ffi_element
}
}
impl From<ListExprElement> for cxx::UniquePtr<crate::ffi::ListExprElement> {
fn from(element: ListExprElement) -> Self {
Self::from(&element)
}
}
impl From<&crate::ffi::ListExprElement> for ListExprElement {
fn from(value: &crate::ffi::ListExprElement) -> Self {
ListExprElement {
expr: Expr::from(value.expr()),
optional: value.optional(),
}
}
}
impl From<cxx::UniquePtr<crate::ffi::ListExprElement>> for ListExprElement {
fn from(value: cxx::UniquePtr<crate::ffi::ListExprElement>) -> Self {
Self::from(&*value)
}
}
impl From<&StructExprField> for cxx::UniquePtr<crate::ffi::StructExprField> {
fn from(value: &StructExprField) -> Self {
use crate::ffi::StructExprField as FfiStructExprField;
let mut ffi_field = FfiStructExprField::new();
ffi_field.pin_mut().set_id(value.id);
ffi_field.pin_mut().set_name(value.name.as_str().into());
ffi_field.pin_mut().set_value((&value.value).into());
ffi_field.pin_mut().set_optional(value.optional);
ffi_field
}
}
impl From<StructExprField> for cxx::UniquePtr<crate::ffi::StructExprField> {
fn from(value: StructExprField) -> Self {
Self::from(&value)
}
}
impl From<&crate::ffi::StructExprField> for StructExprField {
fn from(value: &crate::ffi::StructExprField) -> Self {
StructExprField {
id: value.id(),
name: value.name().to_string(),
value: Expr::from(value.value()),
optional: value.optional(),
}
}
}
impl From<cxx::UniquePtr<crate::ffi::StructExprField>> for StructExprField {
fn from(value: cxx::UniquePtr<crate::ffi::StructExprField>) -> Self {
Self::from(&*value)
}
}
impl From<&MapExprEntry> for cxx::UniquePtr<crate::ffi::MapExprEntry> {
fn from(value: &MapExprEntry) -> Self {
use crate::ffi::MapExprEntry as FfiMapExprEntry;
let mut ffi_entry = FfiMapExprEntry::new();
ffi_entry.pin_mut().set_id(value.id);
ffi_entry.pin_mut().set_key((&value.key).into());
ffi_entry.pin_mut().set_value((&value.value).into());
ffi_entry.pin_mut().set_optional(value.optional);
ffi_entry
}
}
impl From<MapExprEntry> for cxx::UniquePtr<crate::ffi::MapExprEntry> {
fn from(value: MapExprEntry) -> Self {
Self::from(&value)
}
}
impl From<&crate::ffi::MapExprEntry> for MapExprEntry {
fn from(value: &crate::ffi::MapExprEntry) -> Self {
MapExprEntry {
id: value.id(),
key: Expr::from(value.key()),
value: Expr::from(value.value()),
optional: value.optional(),
}
}
}
impl From<cxx::UniquePtr<crate::ffi::MapExprEntry>> for MapExprEntry {
fn from(value: cxx::UniquePtr<crate::ffi::MapExprEntry>) -> Self {
Self::from(&*value)
}
}