mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 04:02:20 +00:00
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>
This commit is contained in:
parent
6d1c22d0ac
commit
c6945acad7
@ -20,12 +20,28 @@ enum Value {
|
||||
Boolean(bool),
|
||||
Number(i32),
|
||||
String(String),
|
||||
Array(Vec<Value>),
|
||||
Object(Object),
|
||||
}
|
||||
|
||||
type Object = Vec<(String, Value)>;
|
||||
|
||||
/// Minimal "almost JSON" generator (e.g. no `null`s, no arrays, no escaping),
|
||||
fn comma_sep<T>(
|
||||
seq: &[T],
|
||||
formatter: &mut Formatter<'_>,
|
||||
f: impl Fn(&mut Formatter<'_>, &T) -> Result,
|
||||
) -> Result {
|
||||
if let [ref rest @ .., ref last] = seq[..] {
|
||||
for v in rest {
|
||||
f(formatter, v)?;
|
||||
formatter.write_str(",")?;
|
||||
}
|
||||
f(formatter, last)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Minimal "almost JSON" generator (e.g. no `null`s, no escaping),
|
||||
/// enough for this purpose.
|
||||
impl Display for Value {
|
||||
fn fmt(&self, formatter: &mut Formatter<'_>) -> Result {
|
||||
@ -33,59 +49,67 @@ impl Display for Value {
|
||||
Value::Boolean(boolean) => write!(formatter, "{}", boolean),
|
||||
Value::Number(number) => write!(formatter, "{}", number),
|
||||
Value::String(string) => write!(formatter, "\"{}\"", string),
|
||||
Value::Array(values) => {
|
||||
formatter.write_str("[")?;
|
||||
comma_sep(&values[..], formatter, |formatter, v| v.fmt(formatter))?;
|
||||
formatter.write_str("]")
|
||||
}
|
||||
Value::Object(object) => {
|
||||
formatter.write_str("{")?;
|
||||
if let [ref rest @ .., ref last] = object[..] {
|
||||
for (key, value) in rest {
|
||||
write!(formatter, "\"{}\": {},", key, value)?;
|
||||
}
|
||||
write!(formatter, "\"{}\": {}", last.0, last.1)?;
|
||||
}
|
||||
comma_sep(&object[..], formatter, |formatter, v| {
|
||||
write!(formatter, "\"{}\": {}", v.0, v.1)
|
||||
})?;
|
||||
formatter.write_str("}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bool> for Value {
|
||||
fn from(value: bool) -> Self {
|
||||
Self::Boolean(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i32> for Value {
|
||||
fn from(value: i32) -> Self {
|
||||
Self::Number(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for Value {
|
||||
fn from(value: String) -> Self {
|
||||
Self::String(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for Value {
|
||||
fn from(value: &str) -> Self {
|
||||
Self::String(value.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Object> for Value {
|
||||
fn from(object: Object) -> Self {
|
||||
Self::Object(object)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Into<Value>, const N: usize> From<[T; N]> for Value {
|
||||
fn from(i: [T; N]) -> Self {
|
||||
Self::Array(i.into_iter().map(|v| v.into()).collect())
|
||||
}
|
||||
}
|
||||
|
||||
struct TargetSpec(Object);
|
||||
|
||||
impl TargetSpec {
|
||||
fn new() -> TargetSpec {
|
||||
TargetSpec(Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
trait Push<T> {
|
||||
fn push(&mut self, key: &str, value: T);
|
||||
}
|
||||
|
||||
impl Push<bool> for TargetSpec {
|
||||
fn push(&mut self, key: &str, value: bool) {
|
||||
self.0.push((key.to_string(), Value::Boolean(value)));
|
||||
}
|
||||
}
|
||||
|
||||
impl Push<i32> for TargetSpec {
|
||||
fn push(&mut self, key: &str, value: i32) {
|
||||
self.0.push((key.to_string(), Value::Number(value)));
|
||||
}
|
||||
}
|
||||
|
||||
impl Push<String> for TargetSpec {
|
||||
fn push(&mut self, key: &str, value: String) {
|
||||
self.0.push((key.to_string(), Value::String(value)));
|
||||
}
|
||||
}
|
||||
|
||||
impl Push<&str> for TargetSpec {
|
||||
fn push(&mut self, key: &str, value: &str) {
|
||||
self.push(key, value.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
impl Push<Object> for TargetSpec {
|
||||
fn push(&mut self, key: &str, value: Object) {
|
||||
self.0.push((key.to_string(), Value::Object(value)));
|
||||
fn push(&mut self, key: &str, value: impl Into<Value>) {
|
||||
self.0.push((key.to_string(), value.into()));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user