use crate::model::constraints::{PredicateValue, SequenceBuilder};
use crate::model::identifiers::{Identifier, IdentifierReference, QualifiedIdentifier};
use crate::model::Span;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub enum Term {
Sequence(Box<SequenceBuilder>),
Function(Box<FunctionalTerm>),
Composition(FunctionComposition),
Identifier(IdentifierReference),
ReservedSelf,
Value(PredicateValue),
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct FunctionComposition {
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
span: Option<Box<Span>>,
subject: Subject, function_names: Vec<Identifier>, }
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub enum Subject {
ReservedSelf,
Identifier(Identifier),
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct FunctionalTerm {
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
span: Option<Box<Span>>,
function: Term,
arguments: Vec<Term>,
}
impl From<FunctionComposition> for Term {
fn from(v: FunctionComposition) -> Self {
Self::Composition(v)
}
}
impl From<IdentifierReference> for Term {
fn from(v: IdentifierReference) -> Self {
Self::Identifier(v)
}
}
impl From<Identifier> for Term {
fn from(v: Identifier) -> Self {
Self::Identifier(v.into())
}
}
impl From<QualifiedIdentifier> for Term {
fn from(v: QualifiedIdentifier) -> Self {
Self::Identifier(v.into())
}
}
impl From<PredicateValue> for Term {
fn from(v: PredicateValue) -> Self {
Self::Value(v)
}
}
impl From<FunctionalTerm> for Term {
fn from(v: FunctionalTerm) -> Self {
Self::Function(Box::new(v))
}
}
impl From<Box<FunctionalTerm>> for Term {
fn from(v: Box<FunctionalTerm>) -> Self {
Self::Function(v)
}
}
impl From<SequenceBuilder> for Term {
fn from(v: SequenceBuilder) -> Self {
Self::Sequence(Box::new(v))
}
}
impl From<Box<SequenceBuilder>> for Term {
fn from(v: Box<SequenceBuilder>) -> Self {
Self::Sequence(v)
}
}
impl Term {
is_as_variant!(Sequence (SequenceBuilder) => is_sequence, as_sequence);
is_as_variant!(Function (FunctionalTerm) => is_function, as_function);
is_as_variant!(Composition (FunctionComposition) => is_call, as_call);
is_as_variant!(Identifier (IdentifierReference) => is_identifier, as_identifier);
is_as_variant!(Value (PredicateValue) => is_value, as_value);
}
impl_has_source_span_for!(FunctionComposition);
impl FunctionComposition {
pub fn new<S, N>(subject: S, function_names: N) -> Self
where
S: Into<Subject>,
N: Into<Vec<Identifier>>,
{
let function_names = function_names.into();
assert!(!function_names.is_empty());
Self {
span: Default::default(),
subject: subject.into(),
function_names,
}
}
pub fn subject(&self) -> &Subject {
&self.subject
}
pub fn set_subject<S>(&mut self, subject: S)
where
S: Into<Subject>,
{
self.subject = subject.into();
}
get_and_set_vec!(
pub
has has_function_names,
function_names_len,
function_names,
function_names_mut,
add_to_function_names,
extend_function_names
=> function_names, Identifier
);
}
impl From<Identifier> for Subject {
fn from(v: Identifier) -> Self {
Self::Identifier(v)
}
}
impl Subject {
is_variant!(ReservedSelf => is_reservesd_self);
is_as_variant!(Identifier (Identifier) => is_identifier, as_identifier);
}
impl_has_source_span_for!(FunctionalTerm);
impl FunctionalTerm {
pub fn new<T>(function: T) -> Self
where
T: Into<Term>,
{
Self {
span: Default::default(),
function: function.into(),
arguments: Default::default(),
}
}
pub fn new_with_arguments<T, A>(function: T, arguments: A) -> Self
where
T: Into<Term>,
A: Into<Vec<Term>>,
{
Self {
span: Default::default(),
function: function.into(),
arguments: arguments.into(),
}
}
get_and_set!(pub function, set_function => Term);
get_and_set_vec!(
pub
has has_arguments,
arguments_len,
arguments,
arguments_mut,
add_to_arguments,
extend_arguments
=> arguments, Term
);
}