hcl/expr/variable.rs
1use crate::{Identifier, InternalString, Result};
2use serde::Deserialize;
3use std::ops::Deref;
4
5/// A type representing a variable in an HCL expression.
6///
7/// It is a wrapper around the [`Identifier`] type and behaves the same in most cases via its
8/// `Deref` implementation.
9///
10/// This is a separate type to differentiate between bare identifiers and variable identifiers
11/// which have different semantics in different scopes.
12#[derive(Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
13#[serde(transparent)]
14pub struct Variable(Identifier);
15
16impl Variable {
17 /// Create a new `Variable` after validating that it only contains characters that are allowed
18 /// in HCL identifiers.
19 ///
20 /// See the documentation of [`Identifier::new`] for more.
21 ///
22 /// # Errors
23 ///
24 /// If `ident` contains characters that are not allowed in HCL identifiers or if it is empty an
25 /// error will be returned.
26 pub fn new<T>(ident: T) -> Result<Self>
27 where
28 T: Into<InternalString>,
29 {
30 Identifier::new(ident).map(Variable)
31 }
32
33 /// Create a new `Variable` after sanitizing the input if necessary.
34 ///
35 /// See the documentation of [`Identifier::sanitized`] for more.
36 pub fn sanitized<T>(ident: T) -> Self
37 where
38 T: AsRef<str>,
39 {
40 Variable(Identifier::sanitized(ident))
41 }
42
43 /// Create a new `Variable` from an identifier without checking if it is valid in HCL.
44 ///
45 /// It is the caller's responsibility to ensure that the variable identifier is valid.
46 ///
47 /// See the documentation of [`Identifier::unchecked`] for more.
48 ///
49 /// # Safety
50 ///
51 /// This function is not marked as unsafe because it does not cause undefined behaviour.
52 /// However, attempting to serialize an invalid variable identifier to HCL will produce invalid
53 /// output.
54 pub fn unchecked<T>(ident: T) -> Self
55 where
56 T: Into<InternalString>,
57 {
58 Variable(Identifier::unchecked(ident))
59 }
60
61 /// Consume `self` and return the wrapped `Identifier`.
62 pub fn into_inner(self) -> Identifier {
63 self.0
64 }
65}
66
67impl Deref for Variable {
68 type Target = Identifier;
69
70 fn deref(&self) -> &Self::Target {
71 &self.0
72 }
73}
74
75impl From<Identifier> for Variable {
76 fn from(ident: Identifier) -> Self {
77 Variable(ident)
78 }
79}