conjure_core/ast/
name.rs

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