conjure_cp_core/ast/
name.rs

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