conjure_cp_core/ast/
reference.rs1use crate::ast::declaration::serde::DeclarationPtrAsId;
2use crate::ast::serde::HasId;
3use crate::{ast::DeclarationPtr, bug};
4use derivative::Derivative;
5use serde::{Deserialize, Serialize};
6use serde_with::serde_as;
7use std::fmt::{Display, Formatter};
8use uniplate::Uniplate;
9
10use super::{
11 DomainPtr, Expression, GroundDomain, Metadata, Moo, Name,
12 categories::{Category, CategoryOf},
13 domains::HasDomain,
14};
15
16#[serde_as]
22#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Uniplate, Derivative)]
23#[derivative(Hash)]
24#[uniplate()]
25#[biplate(to=DeclarationPtr)]
26#[biplate(to=Name)]
27pub struct Reference {
28 #[serde_as(as = "DeclarationPtrAsId")]
29 pub ptr: DeclarationPtr,
30}
31
32impl Reference {
33 pub fn new(ptr: DeclarationPtr) -> Self {
34 Reference { ptr }
35 }
36
37 pub fn ptr(&self) -> &DeclarationPtr {
38 &self.ptr
39 }
40
41 pub fn into_ptr(self) -> DeclarationPtr {
42 self.ptr
43 }
44
45 pub fn name(&self) -> std::cell::Ref<'_, Name> {
46 self.ptr.name()
47 }
48
49 pub fn id(&self) -> crate::ast::serde::ObjId {
50 self.ptr.id()
51 }
52
53 pub fn domain(&self) -> Option<DomainPtr> {
54 self.ptr.domain()
55 }
56
57 pub fn resolved_domain(&self) -> Option<Moo<GroundDomain>> {
58 self.domain()?.resolve()
59 }
60}
61
62impl From<Reference> for Expression {
63 fn from(value: Reference) -> Self {
64 Expression::Atomic(Metadata::new(), value.into())
65 }
66}
67
68impl From<DeclarationPtr> for Reference {
69 fn from(ptr: DeclarationPtr) -> Self {
70 Reference::new(ptr)
71 }
72}
73
74impl CategoryOf for Reference {
75 fn category_of(&self) -> Category {
76 self.ptr.category_of()
77 }
78}
79
80impl HasDomain for Reference {
81 fn domain_of(&self) -> DomainPtr {
82 self.ptr.domain().unwrap_or_else(|| {
83 bug!(
84 "reference ({name}) should have a domain",
85 name = self.ptr.name()
86 )
87 })
88 }
89}
90
91impl Display for Reference {
92 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
93 self.ptr.name().fmt(f)
94 }
95}