use std::borrow::Borrow;
use std::borrow::Cow;
use string_share::InternedString;
pub use bad_idea::BrokenF32;
pub trait ATermFactory<'s> {
type ATerm: ATerm<'s, Rec = Self::ATermRef>;
type ATermRef: Borrow<Self::ATerm>;
fn int(&'s self, value: i32) -> Self::ATermRef;
fn string<S>(&'s self, value: S) -> Self::ATermRef
where
S: Into<Cow<'s, str>>;
fn tuple<I>(&'s self, children: I) -> Self::ATermRef
where
I: IntoIterator<Item = Self::ATermRef>;
fn real(&'s self, value: f32) -> Self::ATermRef;
fn application<I, S>(&'s self, constructor: S, children: I) -> Self::ATermRef
where
I: IntoIterator<Item = Self::ATermRef>,
S: Into<Cow<'s, str>>;
fn list<I>(&'s self, value: I) -> Self::ATermRef
where
I: IntoIterator<Item = Self::ATermRef>;
fn placeholder(&'s self, value: TermPlaceholder<Self::ATermRef>) -> Self::ATermRef;
fn blob(&'s self, value: <Self::ATerm as ATerm<'s>>::Blob) -> Self::ATermRef;
fn long(&'s self, value: i64) -> Self::ATermRef;
fn with_annos<A>(&'s self, term: Self::ATermRef, annos: A) -> Self::ATermRef
where
A: IntoIterator<Item = Self::ATermRef>;
}
pub trait SharedATermFactory<'s>: ATermFactory<'s> {
fn get_shared(&'s self, value: Self::ATermRef) -> Self::ATermRef;
}
pub trait ATerm<'s> {
type Rec: Borrow<Self>;
type Blob;
#[inline]
fn get_annotations(&self) -> &[Self::Rec];
#[inline]
fn get_int(&self) -> Option<i32>;
#[inline]
fn get_long(&self) -> Option<i64>;
#[inline]
fn get_real(&self) -> Option<f32>;
#[inline]
fn get_application(&self) -> Option<(InternedString<'s>, &[Self::Rec])>;
#[inline]
fn get_list(&self) -> Option<Vec<Self::Rec>>;
#[inline]
fn get_placeholder(&self) -> Option<&TermPlaceholder<Self::Rec>>;
#[inline]
fn get_blob(&self) -> Option<&Self::Blob>;
}
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub enum TermPlaceholder<Rec> {
Int,
String,
Real,
Term,
Application(Box<[Rec]>),
List,
Placeholder,
Blob,
Long,
}
impl<Rec> TermPlaceholder<Rec> {
pub fn cons_string(&self) -> &'static str {
use TermPlaceholder::*;
match *self {
Int => "int",
String => "string",
Real => "real",
Term => "term",
Application(_) => "appl",
List => "list",
Placeholder => "placeholder",
Blob => "blob",
Long => "long",
}
}
pub fn to_template<'s, F>(&self, factory: &'s F) -> Rec
where
F: ATermFactory<'s, ATermRef = Rec>,
Rec: Clone + Borrow<<F as ATermFactory<'s>>::ATerm>,
{
use TermPlaceholder::*;
match *self {
Int | String | Real | Term | List | Placeholder | Blob | Long => {
factory.application(self.cons_string(), ::std::iter::empty())
}
Application(ref args) => factory.application(self.cons_string(), args.iter().cloned()),
}
}
}
impl<AR> ::print::ATermWrite for TermPlaceholder<AR>
where
AR: ::print::ATermWrite,
{
fn to_ascii<W: ::std::fmt::Write>(&self, writer: &mut W) -> ::std::fmt::Result {
use interface::TermPlaceholder::*;
match *self {
Int | String | Real | Term | List | Placeholder | Blob | Long => {
write!(writer, "<{}>", self.cons_string())
}
Application(ref args) => {
write!(writer, "<{}(", self.cons_string())?;
(**args).to_ascii(writer)?;
write!(writer, ")>")
}
}
}
}