microcad_lang/value/
target.rs

1// Copyright © 2025 The µcad authors <info@ucad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4//! Type for a lookup result.
5
6use crate::{syntax::*, value::*};
7
8/// Type for a lookup result.
9#[derive(Clone, Default, PartialEq)]
10pub struct Target {
11    /// Name that has been looked up.
12    pub name: QualifiedName,
13    /// Found target name if any.
14    pub target: Option<QualifiedName>,
15}
16
17impl Target {
18    /// Create new target.
19    pub fn new(name: QualifiedName, target: Option<QualifiedName>) -> Self {
20        Self { name, target }
21    }
22    /// Return `true` if target is valid.
23    pub fn is_valid(&self) -> bool {
24        self.target.is_some()
25    }
26
27    /// Return `true` if target is not valid.
28    pub fn is_invalid(&self) -> bool {
29        !self.is_valid()
30    }
31}
32
33impl std::fmt::Display for Target {
34    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35        let name = &self.name;
36        if let Some(target) = &self.target {
37            write!(f, "{{{name} -> {target}}}")
38        } else {
39            write!(f, "{{{name} -> ???}}")
40        }
41    }
42}
43
44impl std::fmt::Debug for Target {
45    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46        let name = &self.name;
47        if let Some(target) = &self.target {
48            write!(f, "{{{name:?} -> {target:?}}}")
49        } else if cfg!(feature = "ansi-color") {
50            color_print::cwrite!(f, "{{{name:?} -> <R!>???</>}}")
51        } else {
52            write!(f, "{{{name:?} -> ???}}")
53        }
54    }
55}
56
57impl TryFrom<&Value> for Target {
58    type Error = ValueError;
59
60    fn try_from(value: &Value) -> Result<Self, Self::Error> {
61        if let Value::Target(target) = value {
62            Ok(target.clone())
63        } else {
64            Err(ValueError::CannotConvert(
65                value.ty().to_string(),
66                "target".into(),
67            ))
68        }
69    }
70}
71
72impl std::hash::Hash for Target {
73    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
74        self.name.hash(state);
75        self.target.hash(state);
76    }
77}