1better_scoped_tls::scoped_tls!(static FLAVOR: Flavor);
2
3#[repr(u8)]
4#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Default)]
5pub enum Flavor {
6 #[default]
7 Babel,
8 Acorn {
9 extra_comments: bool,
10 },
11}
12
13impl Flavor {
14 pub fn with<F, Ret>(self, op: F) -> Ret
15 where
16 F: FnOnce() -> Ret,
17 {
18 FLAVOR.set(&self, op)
19 }
20
21 pub fn current() -> Self {
22 if FLAVOR.is_set() {
23 FLAVOR.with(|v| *v)
24 } else {
25 Flavor::default()
26 }
27 }
28
29 pub fn emit_loc(&self) -> bool {
30 true
31 }
32
33 pub(crate) fn skip_range(_: &Option<[u32; 2]>) -> bool {
34 matches!(Self::current(), Flavor::Babel)
35 }
36
37 pub(crate) fn skip_empty<T>(v: &T) -> bool
38 where
39 T: IsEmpty,
40 {
41 matches!(Self::current(), Flavor::Acorn { .. }) && v.is_empty()
42 }
43
44 pub(crate) fn skip_none<T>(v: &Option<T>) -> bool {
45 matches!(Self::current(), Flavor::Acorn { .. }) && v.is_none()
46 }
47
48 pub(crate) fn skip_none_and_false(v: &Option<bool>) -> bool {
49 matches!(Self::current(), Flavor::Acorn { .. }) && matches!(v, None | Some(false))
50 }
51}
52
53pub(crate) trait IsEmpty {
54 fn is_empty(&self) -> bool;
55}
56
57impl IsEmpty for String {
58 fn is_empty(&self) -> bool {
59 self.is_empty()
60 }
61}
62
63impl<T> IsEmpty for Vec<T> {
64 fn is_empty(&self) -> bool {
65 self.is_empty()
66 }
67}
68
69impl<T> IsEmpty for Option<T>
70where
71 T: IsEmpty,
72{
73 fn is_empty(&self) -> bool {
74 match self {
75 Some(v) => v.is_empty(),
76 None => true,
77 }
78 }
79}