conjure_cp_core/ast/
name.rs

1use std::fmt::Display;
2
3use itertools::Itertools as _;
4use polyquine::Quine;
5use serde::{Deserialize, Serialize};
6use ustr::Ustr;
7
8/// A reference to an object stored in the [`SymbolTable`].
9#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize, Quine)]
10#[path_prefix(conjure_cp::ast)]
11pub enum Name {
12    /// A name given in the input model.
13    User(Ustr),
14    /// A name generated by Conjure-Oxide.
15    Machine(i32),
16
17    /// An auxiliary variable which is part of a Representation of a larger one.
18    /// See [crate::representation::Representation]
19    Represented(
20        // box these fields to make the size of name smaller
21        // this in turn makes the size of atom, expression, domain, ... smaller
22        Box<(
23            // The source variable
24            Name,
25            // The representation rule used
26            Ustr,
27            // Additional, rule dependent, information
28            Ustr,
29        )>,
30    ),
31
32    /// A variable divided into several auxiliary ones through a Representation.
33    WithRepresentation(
34        Box<Name>,
35        /// representations chosen
36        Vec<Ustr>,
37    ),
38}
39
40impl Name {
41    /// Creates a new `Name::User` from a `&str`.
42    pub fn user(name: &str) -> Self {
43        Name::User(Ustr::from(name))
44    }
45}
46
47impl Default for Name {
48    fn default() -> Self {
49        Name::User(Ustr::from(""))
50    }
51}
52
53uniplate::derive_unplateable!(Name);
54
55impl Display for Name {
56    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57        match self {
58            Name::User(s) => write!(f, "{s}"),
59            Name::Machine(i) => write!(f, "__{i}"),
60            Name::Represented(fields) => {
61                let (name, rule_string, suffix) = fields.as_ref();
62                write!(f, "{name}#{rule_string}_{suffix}")
63            }
64            Name::WithRepresentation(name, items) => {
65                // TODO: what is the correct syntax for nested reprs?
66                write!(f, "{name}#{}", items.iter().join("#"))
67            }
68        }
69    }
70}
71
72impl From<&str> for Name {
73    fn from(s: &str) -> Self {
74        Name::User(Ustr::from(s))
75    }
76}
77
78impl From<i32> for Name {
79    fn from(i: i32) -> Self {
80        Name::Machine(i)
81    }
82}