hcl_edit/
repr.rs

1//! Representations of values within a HCL document.
2
3use crate::encode::{Encode, EncodeState};
4use crate::raw_string::RawString;
5use std::fmt::{self, Write};
6use std::ops::{Deref, DerefMut, Range};
7
8/// Represents the whitespace and comments before (the "prefix") or after (the "suffix") a HCL value.
9#[derive(Debug, Clone, PartialEq, Eq, Default)]
10pub struct Decor {
11    prefix: Option<RawString>,
12    suffix: Option<RawString>,
13}
14
15impl Decor {
16    /// Creates a new `Decor` for a prefix and a suffix.
17    pub fn new(prefix: impl Into<RawString>, suffix: impl Into<RawString>) -> Decor {
18        Decor {
19            prefix: Some(prefix.into()),
20            suffix: Some(suffix.into()),
21        }
22    }
23
24    /// Sets the decor prefix.
25    pub fn set_prefix(&mut self, prefix: impl Into<RawString>) {
26        self.prefix = Some(prefix.into());
27    }
28
29    /// Sets the decor suffix.
30    pub fn set_suffix(&mut self, suffix: impl Into<RawString>) {
31        self.suffix = Some(suffix.into());
32    }
33
34    /// Returns a reference to the decor prefix, if one is present, `None` otherwise.
35    pub fn prefix(&self) -> Option<&RawString> {
36        self.prefix.as_ref()
37    }
38
39    /// Returns a reference to the decor suffix, if one is present, `None` otherwise.
40    pub fn suffix(&self) -> Option<&RawString> {
41        self.suffix.as_ref()
42    }
43
44    /// Clears the decor prefix and suffix.
45    pub fn clear(&mut self) {
46        self.prefix = None;
47        self.suffix = None;
48    }
49
50    pub(crate) fn encode_prefix(&self, buf: &mut EncodeState, default: &str) -> fmt::Result {
51        if let Some(prefix) = self.prefix() {
52            prefix.encode_with_default(buf, default)
53        } else {
54            buf.write_str(default)
55        }
56    }
57
58    pub(crate) fn encode_suffix(&self, buf: &mut EncodeState, default: &str) -> fmt::Result {
59        if let Some(suffix) = self.suffix() {
60            suffix.encode_with_default(buf, default)
61        } else {
62            buf.write_str(default)
63        }
64    }
65
66    pub(crate) fn despan(&mut self, input: &str) {
67        if let Some(prefix) = &mut self.prefix {
68            prefix.despan(input);
69        }
70
71        if let Some(suffix) = &mut self.suffix {
72            suffix.despan(input);
73        }
74    }
75}
76
77impl<P, S> From<(P, S)> for Decor
78where
79    P: Into<RawString>,
80    S: Into<RawString>,
81{
82    fn from((prefix, suffix): (P, S)) -> Self {
83        Decor::new(prefix, suffix)
84    }
85}
86
87/// A trait for objects which carry span information.
88pub trait Span {
89    /// Obtains the span information. This only returns `Some` if the value was emitted by the
90    /// parser.
91    ///
92    /// The returned range represents a zero-based start and end byte offset in the input from
93    /// which this object was parsed.
94    fn span(&self) -> Option<Range<usize>>;
95}
96
97impl<T> Span for Box<T>
98where
99    T: Span,
100{
101    fn span(&self) -> Option<Range<usize>> {
102        (**self).span()
103    }
104}
105
106pub(crate) trait SetSpan {
107    fn set_span(&mut self, span: Range<usize>);
108}
109
110impl<T> SetSpan for Box<T>
111where
112    T: SetSpan,
113{
114    fn set_span(&mut self, span: Range<usize>) {
115        (**self).set_span(span);
116    }
117}
118
119/// A trait for objects which can be decorated with whitespace and comments.
120pub trait Decorate {
121    /// Returns a reference to the object's [`Decor`].
122    fn decor(&self) -> &Decor;
123
124    /// Returns a mutable reference to the object's [`Decor`].
125    fn decor_mut(&mut self) -> &mut Decor;
126
127    /// Decorate the object with `decor` in-place.
128    fn decorate(&mut self, decor: impl Into<Decor>) {
129        *self.decor_mut() = decor.into();
130    }
131
132    /// Decorate the object with `decor` and return the modified value.
133    fn decorated(mut self, decor: impl Into<Decor>) -> Self
134    where
135        Self: Sized,
136    {
137        self.decorate(decor);
138        self
139    }
140}
141
142impl<T> Decorate for Box<T>
143where
144    T: Decorate,
145{
146    fn decor(&self) -> &Decor {
147        (**self).decor()
148    }
149
150    fn decor_mut(&mut self) -> &mut Decor {
151        (**self).decor_mut()
152    }
153}
154
155/// A wrapper type for attaching span information to a value.
156#[derive(Debug, Clone, Eq)]
157pub struct Spanned<T> {
158    value: T,
159    span: Option<Range<usize>>,
160}
161
162impl<T> Spanned<T> {
163    /// Creates a new `Spanned<T>` from a `T`.
164    pub fn new(value: T) -> Spanned<T> {
165        Spanned { value, span: None }
166    }
167
168    /// Consumes the `Spanned<T>` and returns the wrapped value.
169    pub fn into_value(self) -> T {
170        self.value
171    }
172
173    /// Returns a reference to the wrapped value.
174    pub fn value(&self) -> &T {
175        &self.value
176    }
177
178    /// Returns a mutable reference to the wrapped value.
179    pub fn value_mut(&mut self) -> &mut T {
180        &mut self.value
181    }
182
183    /// Consumes the `Spanned<T>` and converts the inner value into another type.
184    #[inline]
185    pub fn value_into<U>(self) -> U
186    where
187        T: Into<U>,
188    {
189        self.value.into()
190    }
191}
192
193impl<T> PartialEq for Spanned<T>
194where
195    T: PartialEq,
196{
197    fn eq(&self, other: &Self) -> bool {
198        self.value == other.value
199    }
200}
201
202impl<T> AsRef<T> for Spanned<T> {
203    #[inline]
204    fn as_ref(&self) -> &T {
205        self.value()
206    }
207}
208
209impl<T> AsMut<T> for Spanned<T> {
210    #[inline]
211    fn as_mut(&mut self) -> &mut T {
212        self.value_mut()
213    }
214}
215
216impl<T> Deref for Spanned<T> {
217    type Target = T;
218
219    #[inline]
220    fn deref(&self) -> &T {
221        self.as_ref()
222    }
223}
224
225impl<T> DerefMut for Spanned<T> {
226    #[inline]
227    fn deref_mut(&mut self) -> &mut T {
228        self.as_mut()
229    }
230}
231
232impl<T> From<T> for Spanned<T> {
233    fn from(value: T) -> Self {
234        Spanned::new(value)
235    }
236}
237
238impl<T> Span for Spanned<T> {
239    fn span(&self) -> Option<Range<usize>> {
240        self.span.clone()
241    }
242}
243
244impl<T> SetSpan for Spanned<T> {
245    fn set_span(&mut self, span: Range<usize>) {
246        self.span = Some(span);
247    }
248}
249
250impl<T> fmt::Display for Spanned<T>
251where
252    T: Encode,
253{
254    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
255        let mut state = EncodeState::new(f);
256        self.encode(&mut state)
257    }
258}
259
260/// A wrapper type for attaching a [`Decor`] and span information to a value.
261#[derive(Debug, Clone, Eq)]
262pub struct Decorated<T> {
263    value: T,
264    decor: Decor,
265    span: Option<Range<usize>>,
266}
267
268impl<T> Decorated<T> {
269    /// Creates a new `Decorated<T>` from a `T`.
270    pub fn new(value: T) -> Decorated<T> {
271        Decorated {
272            value,
273            decor: Decor::default(),
274            span: None,
275        }
276    }
277
278    /// Consumes the `Decorated<T>` and returns the wrapped value.
279    pub fn into_value(self) -> T {
280        self.value
281    }
282
283    /// Returns a reference to the wrapped value.
284    pub fn value(&self) -> &T {
285        &self.value
286    }
287
288    /// Returns a mutable reference to the wrapped value.
289    pub fn value_mut(&mut self) -> &mut T {
290        &mut self.value
291    }
292
293    /// Consumes the `Decorated<T>` and converts the inner value into another type.
294    #[inline]
295    pub fn value_into<U>(self) -> U
296    where
297        T: Into<U>,
298    {
299        self.value.into()
300    }
301}
302
303impl<T> PartialEq for Decorated<T>
304where
305    T: PartialEq,
306{
307    fn eq(&self, other: &Self) -> bool {
308        self.value == other.value
309    }
310}
311
312impl<T> AsRef<T> for Decorated<T> {
313    #[inline]
314    fn as_ref(&self) -> &T {
315        self.value()
316    }
317}
318
319impl<T> AsMut<T> for Decorated<T> {
320    #[inline]
321    fn as_mut(&mut self) -> &mut T {
322        self.value_mut()
323    }
324}
325
326impl<T> Deref for Decorated<T> {
327    type Target = T;
328
329    #[inline]
330    fn deref(&self) -> &T {
331        self.as_ref()
332    }
333}
334
335impl<T> DerefMut for Decorated<T> {
336    #[inline]
337    fn deref_mut(&mut self) -> &mut T {
338        self.as_mut()
339    }
340}
341
342impl<T> From<T> for Decorated<T> {
343    fn from(value: T) -> Self {
344        Decorated::new(value)
345    }
346}
347
348impl<T> Decorate for Decorated<T> {
349    fn decor(&self) -> &Decor {
350        &self.decor
351    }
352
353    fn decor_mut(&mut self) -> &mut Decor {
354        &mut self.decor
355    }
356}
357
358impl<T> Span for Decorated<T> {
359    fn span(&self) -> Option<Range<usize>> {
360        self.span.clone()
361    }
362}
363
364impl<T> SetSpan for Decorated<T> {
365    fn set_span(&mut self, span: Range<usize>) {
366        self.span = Some(span);
367    }
368}
369
370impl<T> fmt::Display for Decorated<T>
371where
372    T: Encode,
373{
374    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
375        let mut state = EncodeState::new(f);
376        self.encode(&mut state)
377    }
378}
379
380/// A wrapper type for a value together with its `ToString` representation with additional
381/// [`Decor`] and span infromation attached.
382#[derive(Debug, Clone, Eq)]
383pub struct Formatted<T> {
384    value: T,
385    decor: Decor,
386    repr: Option<RawString>,
387    span: Option<Range<usize>>,
388}
389
390impl<T> Formatted<T>
391where
392    T: ToString,
393{
394    /// Creates a new `Formatted<T>` from a `T`.
395    pub fn new(value: T) -> Formatted<T> {
396        Formatted {
397            value,
398            decor: Decor::default(),
399            repr: None,
400            span: None,
401        }
402    }
403
404    /// Returns the raw string representation of the value, if any.
405    pub fn as_repr(&self) -> Option<&RawString> {
406        self.repr.as_ref()
407    }
408
409    pub(crate) fn set_repr(&mut self, repr: impl Into<RawString>) {
410        self.repr = Some(repr.into());
411    }
412
413    /// Formats the value using its `ToString` representation.
414    pub fn format(&mut self) {
415        self.set_repr(self.value.to_string());
416    }
417}
418
419impl<T> Formatted<T> {
420    /// Consumes the `Formatted<T>` and returns the wrapped value.
421    pub fn into_value(self) -> T {
422        self.value
423    }
424
425    /// Returns a reference to the wrapped value.
426    pub fn value(&self) -> &T {
427        &self.value
428    }
429
430    /// Returns a mutable reference to the wrapped value.
431    pub fn value_mut(&mut self) -> &mut T {
432        &mut self.value
433    }
434
435    /// Consumes the `Formatted<T>` and converts the inner value into another type.
436    #[inline]
437    pub fn value_into<U>(self) -> U
438    where
439        T: Into<U>,
440    {
441        self.value.into()
442    }
443}
444
445impl<T> PartialEq for Formatted<T>
446where
447    T: PartialEq,
448{
449    fn eq(&self, other: &Self) -> bool {
450        self.value == other.value
451    }
452}
453
454impl<T> AsRef<T> for Formatted<T> {
455    #[inline]
456    fn as_ref(&self) -> &T {
457        self.value()
458    }
459}
460
461impl<T> AsMut<T> for Formatted<T> {
462    #[inline]
463    fn as_mut(&mut self) -> &mut T {
464        self.value_mut()
465    }
466}
467
468impl<T> Deref for Formatted<T> {
469    type Target = T;
470
471    #[inline]
472    fn deref(&self) -> &T {
473        self.as_ref()
474    }
475}
476
477impl<T> DerefMut for Formatted<T> {
478    #[inline]
479    fn deref_mut(&mut self) -> &mut T {
480        self.as_mut()
481    }
482}
483
484impl<T> From<T> for Formatted<T>
485where
486    T: ToString,
487{
488    fn from(value: T) -> Self {
489        Formatted::new(value)
490    }
491}
492
493impl<T> Decorate for Formatted<T> {
494    fn decor(&self) -> &Decor {
495        &self.decor
496    }
497
498    fn decor_mut(&mut self) -> &mut Decor {
499        &mut self.decor
500    }
501}
502
503impl<T> Span for Formatted<T> {
504    fn span(&self) -> Option<Range<usize>> {
505        self.span.clone()
506    }
507}
508
509impl<T> SetSpan for Formatted<T> {
510    fn set_span(&mut self, span: Range<usize>) {
511        self.span = Some(span);
512    }
513}
514
515impl<T> fmt::Display for Formatted<T>
516where
517    T: Encode,
518{
519    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
520        let mut state = EncodeState::new(f);
521        self.encode(&mut state)
522    }
523}