1use schemars::{
2 schema::{InstanceType, Schema, SchemaObject, SingleOrVec},
3 JsonSchema,
4};
5
6macro_rules! create_definitions {
7 ($($(#[$meta:meta])* ($name:ident, $idx:expr)),* $(,)?) => {
8 #[derive(Default, Copy, Clone, Eq, PartialEq, Hash)]
9 pub struct FontFeatures {
10 enabled: u64,
11 disabled: u64,
12 }
13
14 impl FontFeatures {
15 $(
16 pub fn $name(&self) -> Option<bool> {
17 if (self.enabled & (1 << $idx)) != 0 {
18 Some(true)
19 } else if (self.disabled & (1 << $idx)) != 0 {
20 Some(false)
21 } else {
22 None
23 }
24 }
25 )*
26 }
27
28 impl std::fmt::Debug for FontFeatures {
29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 let mut debug = f.debug_struct("FontFeatures");
31 $(
32 if let Some(value) = self.$name() {
33 debug.field(stringify!($name), &value);
34 };
35 )*
36 debug.finish()
37 }
38 }
39
40 impl<'de> serde::Deserialize<'de> for FontFeatures {
41 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
42 where
43 D: serde::Deserializer<'de>,
44 {
45 use serde::de::{MapAccess, Visitor};
46 use std::fmt;
47
48 struct FontFeaturesVisitor;
49
50 impl<'de> Visitor<'de> for FontFeaturesVisitor {
51 type Value = FontFeatures;
52
53 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
54 formatter.write_str("a map of font features")
55 }
56
57 fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
58 where
59 M: MapAccess<'de>,
60 {
61 let mut enabled: u64 = 0;
62 let mut disabled: u64 = 0;
63
64 while let Some((key, value)) = access.next_entry::<String, Option<bool>>()? {
65 let idx = match key.as_str() {
66 $(stringify!($name) => $idx,)*
67 _ => continue,
68 };
69 match value {
70 Some(true) => enabled |= 1 << idx,
71 Some(false) => disabled |= 1 << idx,
72 None => {}
73 };
74 }
75 Ok(FontFeatures { enabled, disabled })
76 }
77 }
78
79 let features = deserializer.deserialize_map(FontFeaturesVisitor)?;
80 Ok(features)
81 }
82 }
83
84 impl serde::Serialize for FontFeatures {
85 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
86 where
87 S: serde::Serializer,
88 {
89 use serde::ser::SerializeMap;
90
91 let mut map = serializer.serialize_map(None)?;
92
93 $(
94 let feature = stringify!($name);
95 if let Some(value) = self.$name() {
96 map.serialize_entry(feature, &value)?;
97 }
98 )*
99
100 map.end()
101 }
102 }
103
104 impl JsonSchema for FontFeatures {
105 fn schema_name() -> String {
106 "FontFeatures".into()
107 }
108
109 fn json_schema(_: &mut schemars::gen::SchemaGenerator) -> Schema {
110 let mut schema = SchemaObject::default();
111 let properties = &mut schema.object().properties;
112 let feature_schema = Schema::Object(SchemaObject {
113 instance_type: Some(SingleOrVec::Single(Box::new(InstanceType::Boolean))),
114 ..Default::default()
115 });
116
117 $(
118 properties.insert(stringify!($name).to_owned(), feature_schema.clone());
119 )*
120
121 schema.into()
122 }
123 }
124 };
125}
126
127create_definitions!(
128 (calt, 0),
129 (case, 1),
130 (cpsp, 2),
131 (frac, 3),
132 (liga, 4),
133 (onum, 5),
134 (ordn, 6),
135 (pnum, 7),
136 (ss01, 8),
137 (ss02, 9),
138 (ss03, 10),
139 (ss04, 11),
140 (ss05, 12),
141 (ss06, 13),
142 (ss07, 14),
143 (ss08, 15),
144 (ss09, 16),
145 (ss10, 17),
146 (ss11, 18),
147 (ss12, 19),
148 (ss13, 20),
149 (ss14, 21),
150 (ss15, 22),
151 (ss16, 23),
152 (ss17, 24),
153 (ss18, 25),
154 (ss19, 26),
155 (ss20, 27),
156 (subs, 28),
157 (sups, 29),
158 (swsh, 30),
159 (titl, 31),
160 (tnum, 32),
161 (zero, 33)
162);