Skip to main content

rustidy_format/
tag.rs

1//! Formatter tags
2
3// Imports
4use core::mem;
5
6/// Formatter tag
7// TODO: These should be separated by tags that need scopes,
8//       and tags that are pushed/popped.
9#[derive(PartialEq, Eq, Clone, Copy, Debug)]
10pub enum FormatTag {
11	InsideChain,
12
13	// Note: This attribute only works because every time
14	//       we apply it, there's always whitespace directly
15	//       after to remove it, otherwise it would stay for
16	//       too long and be applied when it's no longer relevant.
17	// TODO: Ideally, we'd assign some "position" to this, but
18	//       during formatting, we no longer necessarily have
19	//       the input ranges.
20	AfterNewline,
21}
22
23/// Formatter tags
24#[derive(Clone, Copy, Debug)]
25pub struct FormatTags {
26	pub inside_chain:  bool,
27	pub after_newline: bool,
28}
29
30impl FormatTags {
31	/// Creates new, empty, tags
32	#[must_use]
33	pub const fn new() -> Self {
34		Self { inside_chain: false, after_newline: false, }
35	}
36
37	/// Adds a tag.
38	///
39	/// Returns if the tag was present
40	pub const fn add(&mut self, tag: FormatTag) -> bool {
41		self.set(tag, true)
42	}
43
44	/// Removes a tag.
45	///
46	/// Returns if the tag was present
47	pub const fn remove(&mut self, tag: FormatTag) -> bool {
48		self.set(tag, false)
49	}
50
51	/// Sets whether a tag is present or not.
52	///
53	/// Returns if the tag was present.
54	pub const fn set(&mut self, tag: FormatTag, present: bool) -> bool {
55		match tag {
56			FormatTag::InsideChain => mem::replace(&mut self.inside_chain, present),
57			FormatTag::AfterNewline => mem::replace(&mut self.after_newline, present),
58		}
59	}
60
61	/// Returns if a tag exists
62	#[must_use]
63	pub const fn contains(&self, tag: FormatTag) -> bool {
64		match tag {
65			FormatTag::InsideChain => self.inside_chain,
66			FormatTag::AfterNewline => self.after_newline,
67		}
68	}
69}
70
71impl Default for FormatTags {
72	fn default() -> Self {
73		Self::new()
74	}
75}