Lines
0 %
Functions
use std::{borrow::Borrow, cell::Ref};
use uniplate::Uniplate;
use super::{
AbstractLiteral, DeclarationPtr, DomainPtr, Expression, Literal, Moo, Name,
categories::{Category, CategoryOf},
domains::HasDomain,
records::RecordValue,
};
use derivative::Derivative;
use polyquine::Quine;
use serde::{Deserialize, Serialize};
/// An `Atom` is an indivisible expression, such as a literal or a reference.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Uniplate, Derivative, Quine)]
#[derivative(Hash)]
#[uniplate()]
#[biplate(to=Literal)]
#[biplate(to=Expression)]
#[biplate(to=AbstractLiteral<Literal>)]
#[biplate(to=RecordValue<Literal>)]
#[biplate(to=DeclarationPtr)]
#[biplate(to=Name)]
#[biplate(to=super::Reference)]
#[path_prefix(conjure_cp::ast)]
pub enum Atom {
Literal(Literal),
#[polyquine_skip]
Reference(super::Reference),
}
impl Atom {
pub fn new_ref(decl: DeclarationPtr) -> Atom {
Atom::Reference(super::Reference::new(decl))
pub fn into_declaration(self) -> DeclarationPtr {
match self {
Atom::Reference(reference) => reference.into_ptr(),
_ => panic!("Called into_declaration on a non-reference Atom"),
impl CategoryOf for Atom {
fn category_of(&self) -> Category {
Atom::Literal(_) => Category::Constant,
Atom::Reference(reference) => reference.category_of(),
impl HasDomain for Atom {
fn domain_of(&self) -> DomainPtr {
Atom::Literal(literal) => literal.domain_of(),
Atom::Reference(reference) => reference.domain_of(),
impl std::fmt::Display for Atom {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Atom::Literal(x) => x.fmt(f),
Atom::Reference(x) => x.fmt(f),
impl From<Literal> for Atom {
fn from(value: Literal) -> Self {
Atom::Literal(value)
impl From<DeclarationPtr> for Atom {
fn from(value: DeclarationPtr) -> Self {
Atom::Reference(super::Reference::new(value))
impl From<super::Reference> for Atom {
fn from(value: super::Reference) -> Self {
Atom::Reference(value)
impl From<i32> for Atom {
fn from(value: i32) -> Self {
Atom::Literal(value.into())
impl From<bool> for Atom {
fn from(value: bool) -> Self {
impl TryFrom<Expression> for Atom {
type Error = &'static str;
fn try_from(value: Expression) -> Result<Self, Self::Error> {
match value {
Expression::Atomic(_, atom) => Ok(atom),
_ => Err("Cannot convert non-atomic expression to Atom"),
impl TryFrom<Box<Expression>> for Atom {
fn try_from(value: Box<Expression>) -> Result<Self, Self::Error> {
TryFrom::try_from(*value)
impl TryFrom<Moo<Expression>> for Atom {
fn try_from(value: Moo<Expression>) -> Result<Self, Self::Error> {
TryFrom::try_from(Moo::unwrap_or_clone(value))
impl<'a> TryFrom<&'a Expression> for &'a Atom {
fn try_from(value: &'a Expression) -> Result<Self, Self::Error> {
impl<'a> TryFrom<&'a Box<Expression>> for &'a Atom {
fn try_from(value: &'a Box<Expression>) -> Result<Self, Self::Error> {
let expr: &'a Expression = value.borrow();
expr.try_into()
impl<'a> TryFrom<&'a Moo<Expression>> for &'a Atom {
fn try_from(value: &'a Moo<Expression>) -> Result<Self, Self::Error> {
impl TryFrom<Atom> for Literal {
fn try_from(value: Atom) -> Result<Self, Self::Error> {
Atom::Literal(l) => Ok(l),
_ => Err("Cannot convert non-literal atom to Literal"),
impl<'a> TryFrom<&'a Atom> for &'a Literal {
fn try_from(value: &'a Atom) -> Result<Self, Self::Error> {
impl TryFrom<Atom> for Name {
Atom::Reference(x) => Ok(x.ptr().name().clone()),
_ => Err("Cannot convert non-reference atom to Name"),
impl<'a> TryFrom<&'a Atom> for Ref<'a, Name> {
Atom::Reference(x) => Ok(x.ptr().name()),
impl TryFrom<Atom> for i32 {
let lit: Literal = value.try_into()?;
lit.try_into()
impl TryFrom<&Box<Atom>> for i32 {
fn try_from(value: &Box<Atom>) -> Result<Self, Self::Error> {
TryFrom::<&Atom>::try_from(value.as_ref())
impl TryFrom<Box<Atom>> for i32 {
fn try_from(value: Box<Atom>) -> Result<Self, Self::Error> {
let lit: Literal = (*value).try_into()?;
impl TryFrom<&Moo<Atom>> for i32 {
fn try_from(value: &Moo<Atom>) -> Result<Self, Self::Error> {
impl TryFrom<Moo<Atom>> for i32 {
fn try_from(value: Moo<Atom>) -> Result<Self, Self::Error> {
impl TryFrom<&Atom> for i32 {
fn try_from(value: &Atom) -> Result<Self, Self::Error> {
let lit: &Literal = value.try_into()?;
impl TryFrom<Atom> for bool {
impl TryFrom<&Atom> for bool {