hcl_edit/structure/attribute.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
use crate::expr::Expression;
use crate::{Decor, Decorate, Decorated, Ident, Span};
use std::ops::{self, Range};
/// Represents an HCL attribute which consists of an attribute key and a value expression.
///
/// In HCL syntax this is represented as:
///
/// ```hcl
/// key = value
/// ```
///
/// Use [`Attribute::new`] to construct an [`Attribute`] from a value that is convertible to this
/// crate's [`Expression`] type.
#[derive(Debug, Clone, Eq)]
pub struct Attribute {
/// The HCL attribute's key.
pub key: Decorated<Ident>,
/// The value expression of the HCL attribute.
pub value: Expression,
decor: Decor,
span: Option<Range<usize>>,
}
impl Attribute {
/// Creates a new `Attribute` from a key and a value.
pub fn new(key: impl Into<Decorated<Ident>>, value: impl Into<Expression>) -> Attribute {
Attribute {
key: key.into(),
value: value.into(),
decor: Decor::default(),
span: None,
}
}
/// Returns `true` if the attribute has the given key.
///
/// # Example
///
/// ```
/// use hcl_edit::{structure::Attribute, Ident};
///
/// let attr = Attribute::new(Ident::new("foo"), "bar");
/// assert!(attr.has_key("foo"));
/// assert!(!attr.has_key("bar"));
/// ```
#[inline]
pub fn has_key(&self, key: &str) -> bool {
self.key.as_str() == key
}
pub(crate) fn despan(&mut self, input: &str) {
self.decor.despan(input);
self.key.decor_mut().despan(input);
self.value.despan(input);
}
}
impl PartialEq for Attribute {
fn eq(&self, other: &Self) -> bool {
self.key == other.key && self.value == other.value
}
}
decorate_impl!(Attribute);
span_impl!(Attribute);
/// Allows mutable access to the value and surrounding [`Decor`] of an [`Attribute`] but not to its
/// key.
///
/// This type wraps the attribute returned by
/// [`Body::get_attribute_mut`](crate::structure::Body::get_attribute_mut) and in the iterator
/// returned by [`Body::attributes_mut`](crate::structure::Body::attributes_mut).
pub struct AttributeMut<'a> {
attr: &'a mut Attribute,
}
impl<'a> AttributeMut<'a> {
pub(crate) fn new(attr: &'a mut Attribute) -> AttributeMut<'a> {
AttributeMut { attr }
}
/// Returns an immutable reference to the wrapped `Attribute`.
pub fn get(&self) -> &Attribute {
self.attr
}
/// Returns a mutable reference to the wrapped `Attribute`'s key's decor.
pub fn key_decor_mut(&mut self) -> &mut Decor {
self.attr.key.decor_mut()
}
/// Returns a mutable reference to the wrapped `Attribute`'s value.
pub fn value_mut(&mut self) -> &mut Expression {
&mut self.attr.value
}
}
impl<'a> ops::Deref for AttributeMut<'a> {
type Target = Attribute;
#[inline]
fn deref(&self) -> &Self::Target {
self.get()
}
}
impl<'a> Decorate for AttributeMut<'a> {
fn decor(&self) -> &Decor {
self.attr.decor()
}
fn decor_mut(&mut self) -> &mut Decor {
self.attr.decor_mut()
}
}
impl<'a> Span for AttributeMut<'a> {
fn span(&self) -> Option<Range<usize>> {
self.attr.span()
}
}