Skip to content

Commit c6945ac

Browse files
maurerojeda
authored andcommitted
rust: support arrays in target JSON
Some configuration options such as the supported sanitizer list are arrays. To support using Rust with sanitizers on x86, we must update the target.json generator to support this case. The Push trait is removed in favor of the From trait because the Push trait doesn't work well in the nested case where you are not really pushing values to a TargetSpec. Signed-off-by: Matthew Maurer <mmaurer@google.com> Signed-off-by: Alice Ryhl <aliceryhl@google.com> Reviewed-by: Gary Guo <gary@garyguo.net> Tested-by: Gatlin Newhouse <gatlin.newhouse@gmail.com> Link: https://lore.kernel.org/r/20240730-target-json-arrays-v1-1-2b376fd0ecf4@google.com Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
1 parent 6d1c22d commit c6945ac

File tree

1 file changed

+53
-29
lines changed

1 file changed

+53
-29
lines changed

scripts/generate_rust_target.rs

Lines changed: 53 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -20,72 +20,96 @@ enum Value {
2020
Boolean(bool),
2121
Number(i32),
2222
String(String),
23+
Array(Vec<Value>),
2324
Object(Object),
2425
}
2526

2627
type Object = Vec<(String, Value)>;
2728

28-
/// Minimal "almost JSON" generator (e.g. no `null`s, no arrays, no escaping),
29+
fn comma_sep<T>(
30+
seq: &[T],
31+
formatter: &mut Formatter<'_>,
32+
f: impl Fn(&mut Formatter<'_>, &T) -> Result,
33+
) -> Result {
34+
if let [ref rest @ .., ref last] = seq[..] {
35+
for v in rest {
36+
f(formatter, v)?;
37+
formatter.write_str(",")?;
38+
}
39+
f(formatter, last)?;
40+
}
41+
Ok(())
42+
}
43+
44+
/// Minimal "almost JSON" generator (e.g. no `null`s, no escaping),
2945
/// enough for this purpose.
3046
impl Display for Value {
3147
fn fmt(&self, formatter: &mut Formatter<'_>) -> Result {
3248
match self {
3349
Value::Boolean(boolean) => write!(formatter, "{}", boolean),
3450
Value::Number(number) => write!(formatter, "{}", number),
3551
Value::String(string) => write!(formatter, "\"{}\"", string),
52+
Value::Array(values) => {
53+
formatter.write_str("[")?;
54+
comma_sep(&values[..], formatter, |formatter, v| v.fmt(formatter))?;
55+
formatter.write_str("]")
56+
}
3657
Value::Object(object) => {
3758
formatter.write_str("{")?;
38-
if let [ref rest @ .., ref last] = object[..] {
39-
for (key, value) in rest {
40-
write!(formatter, "\"{}\": {},", key, value)?;
41-
}
42-
write!(formatter, "\"{}\": {}", last.0, last.1)?;
43-
}
59+
comma_sep(&object[..], formatter, |formatter, v| {
60+
write!(formatter, "\"{}\": {}", v.0, v.1)
61+
})?;
4462
formatter.write_str("}")
4563
}
4664
}
4765
}
4866
}
4967

50-
struct TargetSpec(Object);
51-
52-
impl TargetSpec {
53-
fn new() -> TargetSpec {
54-
TargetSpec(Vec::new())
68+
impl From<bool> for Value {
69+
fn from(value: bool) -> Self {
70+
Self::Boolean(value)
5571
}
5672
}
5773

58-
trait Push<T> {
59-
fn push(&mut self, key: &str, value: T);
74+
impl From<i32> for Value {
75+
fn from(value: i32) -> Self {
76+
Self::Number(value)
77+
}
6078
}
6179

62-
impl Push<bool> for TargetSpec {
63-
fn push(&mut self, key: &str, value: bool) {
64-
self.0.push((key.to_string(), Value::Boolean(value)));
80+
impl From<String> for Value {
81+
fn from(value: String) -> Self {
82+
Self::String(value)
6583
}
6684
}
6785

68-
impl Push<i32> for TargetSpec {
69-
fn push(&mut self, key: &str, value: i32) {
70-
self.0.push((key.to_string(), Value::Number(value)));
86+
impl From<&str> for Value {
87+
fn from(value: &str) -> Self {
88+
Self::String(value.to_string())
7189
}
7290
}
7391

74-
impl Push<String> for TargetSpec {
75-
fn push(&mut self, key: &str, value: String) {
76-
self.0.push((key.to_string(), Value::String(value)));
92+
impl From<Object> for Value {
93+
fn from(object: Object) -> Self {
94+
Self::Object(object)
7795
}
7896
}
7997

80-
impl Push<&str> for TargetSpec {
81-
fn push(&mut self, key: &str, value: &str) {
82-
self.push(key, value.to_string());
98+
impl<T: Into<Value>, const N: usize> From<[T; N]> for Value {
99+
fn from(i: [T; N]) -> Self {
100+
Self::Array(i.into_iter().map(|v| v.into()).collect())
83101
}
84102
}
85103

86-
impl Push<Object> for TargetSpec {
87-
fn push(&mut self, key: &str, value: Object) {
88-
self.0.push((key.to_string(), Value::Object(value)));
104+
struct TargetSpec(Object);
105+
106+
impl TargetSpec {
107+
fn new() -> TargetSpec {
108+
TargetSpec(Vec::new())
109+
}
110+
111+
fn push(&mut self, key: &str, value: impl Into<Value>) {
112+
self.0.push((key.to_string(), value.into()));
89113
}
90114
}
91115

0 commit comments

Comments
 (0)