Skip to content

Commit

Permalink
Added support for List of Array examples. (#177)
Browse files Browse the repository at this point in the history
* Added support for List of Array examples.

* Added tests and fixed a doc issue.

* restored !NOTEs
  • Loading branch information
jerbly authored May 29, 2024
1 parent 29387f5 commit 79b7ec1
Show file tree
Hide file tree
Showing 2 changed files with 202 additions and 7 deletions.
156 changes: 156 additions & 0 deletions crates/weaver_semconv/src/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,14 @@ pub enum Examples {
Bools(Vec<bool>),
/// A array of strings example.
Strings(Vec<String>),
/// List of arrays of integers example.
ListOfInts(Vec<Vec<i64>>),
/// List of arrays of doubles example.
ListOfDoubles(Vec<Vec<OrderedFloat<f64>>>),
/// List of arrays of bools example.
ListOfBools(Vec<Vec<bool>>),
/// List of arrays of strings example.
ListOfStrings(Vec<Vec<String>>),
}

/// The different requirement level specifications.
Expand Down Expand Up @@ -772,6 +780,154 @@ mod tests {
assert_eq!(attr.tag(), Some("tag".to_owned()));
assert!(attr.is_required());
}

#[test]
fn test_examples_bool() {
let yaml = "---\ntrue";
let ex: Examples = serde_yaml::from_str(yaml).unwrap();
assert_eq!(ex, Examples::Bool(true));
}

#[test]
fn test_examples_int() {
let yaml = "---\n42";
let ex: Examples = serde_yaml::from_str(yaml).unwrap();
assert_eq!(ex, Examples::Int(42));
}

#[test]
fn test_examples_double() {
let yaml = "---\n3.15";
let ex: Examples = serde_yaml::from_str(yaml).unwrap();
assert_eq!(ex, Examples::Double(OrderedFloat(3.15)));
}

#[test]
fn test_examples_string() {
let yaml = "---\n\"foo\"";
let ex: Examples = serde_yaml::from_str(yaml).unwrap();
assert_eq!(ex, Examples::String("foo".to_owned()));
}

#[test]
fn test_examples_strings() {
let yaml = "---\n- \"foo\"\n- \"bar\"";
let ex: Examples = serde_yaml::from_str(yaml).unwrap();
assert_eq!(
ex,
Examples::Strings(vec!["foo".to_owned(), "bar".to_owned()])
);
}

#[test]
fn test_examples_ints() {
let yaml = "---\n- 42\n- 43";
let ex: Examples = serde_yaml::from_str(yaml).unwrap();
assert_eq!(ex, Examples::Ints(vec![42, 43]));
}

#[test]
fn test_examples_doubles() {
let yaml = "---\n- 3.15\n- 2.71";
let ex: Examples = serde_yaml::from_str(yaml).unwrap();
assert_eq!(
ex,
Examples::Doubles(vec![OrderedFloat(3.15), OrderedFloat(2.71)])
);
}

#[test]
fn test_examples_bools() {
let yaml = "---\n- true\n- false";
let ex: Examples = serde_yaml::from_str(yaml).unwrap();
assert_eq!(ex, Examples::Bools(vec![true, false]));
}

#[test]
fn test_examples_list_of_ints() {
let yaml = "---\n- [42, 43]\n- [44, 45]";
let ex: Examples = serde_yaml::from_str(yaml).unwrap();
assert_eq!(ex, Examples::ListOfInts(vec![vec![42, 43], vec![44, 45]]));
}

#[test]
fn test_examples_list_of_doubles() {
let yaml = "---\n- [3.15, 2.71]\n- [1.41, 1.61]";
let ex: Examples = serde_yaml::from_str(yaml).unwrap();
assert_eq!(
ex,
Examples::ListOfDoubles(vec![
vec![OrderedFloat(3.15), OrderedFloat(2.71)],
vec![OrderedFloat(1.41), OrderedFloat(1.61)]
])
);
}

#[test]
fn test_examples_list_of_bools() {
let yaml = "---\n- [true, false]\n- [false, true]";
let ex: Examples = serde_yaml::from_str(yaml).unwrap();
assert_eq!(
ex,
Examples::ListOfBools(vec![vec![true, false], vec![false, true]])
);
}

#[test]
fn test_examples_list_of_strings() {
let yaml = "---\n- [\"foo\", \"bar\"]\n- [\"baz\", \"qux\"]";
let ex: Examples = serde_yaml::from_str(yaml).unwrap();
assert_eq!(
ex,
Examples::ListOfStrings(vec![
vec!["foo".to_owned(), "bar".to_owned()],
vec!["baz".to_owned(), "qux".to_owned()]
])
);
}

#[test]
fn test_examples_list_of_ints_array_style() {
let yaml = "[ [42, 43], [44, 45] ]";
let ex: Examples = serde_yaml::from_str(yaml).unwrap();
assert_eq!(ex, Examples::ListOfInts(vec![vec![42, 43], vec![44, 45]]));
}

#[test]
fn test_examples_list_of_doubles_array_style() {
let yaml = "[ [3.15, 2.71], [1.41, 1.61] ]";
let ex: Examples = serde_yaml::from_str(yaml).unwrap();
assert_eq!(
ex,
Examples::ListOfDoubles(vec![
vec![OrderedFloat(3.15), OrderedFloat(2.71)],
vec![OrderedFloat(1.41), OrderedFloat(1.61)]
])
);
}

#[test]
fn test_examples_list_of_bools_array_style() {
let yaml = "[ [true, false], [false, true] ]";
let ex: Examples = serde_yaml::from_str(yaml).unwrap();
assert_eq!(
ex,
Examples::ListOfBools(vec![vec![true, false], vec![false, true]])
);
}

#[test]
fn test_examples_list_of_strings_array_style() {
let yaml = "[ [\"foo\", \"bar\"], [\"baz\", \"qux\"] ]";
let ex: Examples = serde_yaml::from_str(yaml).unwrap();
assert_eq!(
ex,
Examples::ListOfStrings(vec![
vec!["foo".to_owned(), "bar".to_owned()],
vec!["baz".to_owned(), "qux".to_owned()]
])
);
}
}

/// An attribute definition with its provenance (path or URL).
Expand Down
53 changes: 46 additions & 7 deletions crates/weaver_semconv_gen/src/gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,15 @@ fn enum_type_string(members: &[EnumEntriesSpec]) -> &'static str {
}
}

fn write_example_list<Out: Write, Element: std::fmt::Display>(
fn write_example_list<Out: Write, Element: std::fmt::Display + std::fmt::Debug>(
out: &mut Out,
list: &[Element],
is_array: bool,
) -> Result<(), Error> {
if is_array {
write!(out, "`{:?}`", list)?;
return Ok(());
}
let mut first = true;
for e in list {
if !first {
Expand All @@ -73,16 +78,40 @@ fn write_example_list<Out: Write, Element: std::fmt::Display>(
Ok(())
}

fn write_examples_string<Out: Write>(out: &mut Out, examples: &Examples) -> Result<(), Error> {
fn write_example_list_of_lists<Out: Write, Element: std::fmt::Display + std::fmt::Debug>(
out: &mut Out,
list: &[Vec<Element>],
is_array: bool,
) -> Result<(), Error> {
let mut first = true;
for e in list {
if !first {
write!(out, "; ")?;
}
write_example_list(out, e, is_array)?;
first = false;
}
Ok(())
}

fn write_examples_string<Out: Write>(
out: &mut Out,
examples: &Examples,
is_array: bool,
) -> Result<(), Error> {
match examples {
Examples::Bool(value) => Ok(write!(out, "`{value}`")?),
Examples::Int(value) => Ok(write!(out, "`{value}`")?),
Examples::Double(value) => Ok(write!(out, "`{value}`")?),
Examples::String(value) => Ok(write!(out, "`{value}`")?),
Examples::Ints(values) => write_example_list(out, values),
Examples::Doubles(values) => write_example_list(out, values),
Examples::Bools(values) => write_example_list(out, values),
Examples::Strings(values) => write_example_list(out, values),
Examples::Ints(values) => write_example_list(out, values, is_array),
Examples::Doubles(values) => write_example_list(out, values, is_array),
Examples::Bools(values) => write_example_list(out, values, is_array),
Examples::Strings(values) => write_example_list(out, values, is_array),
Examples::ListOfInts(values) => write_example_list_of_lists(out, values, is_array),
Examples::ListOfDoubles(values) => write_example_list_of_lists(out, values, is_array),
Examples::ListOfBools(values) => write_example_list_of_lists(out, values, is_array),
Examples::ListOfStrings(values) => write_example_list_of_lists(out, values, is_array),
}
}

Expand Down Expand Up @@ -183,6 +212,16 @@ impl<'a> AttributeView<'a> {
matches!(&self.attribute.r#type, AttributeType::Enum { .. })
}

fn is_array(&self) -> bool {
matches!(
&self.attribute.r#type,
AttributeType::PrimitiveOrArray(PrimitiveOrArrayTypeSpec::Booleans)
| AttributeType::PrimitiveOrArray(PrimitiveOrArrayTypeSpec::Ints)
| AttributeType::PrimitiveOrArray(PrimitiveOrArrayTypeSpec::Doubles)
| AttributeType::PrimitiveOrArray(PrimitiveOrArrayTypeSpec::Strings)
)
}

fn is_sampling_relevant(&self) -> bool {
self.attribute.sampling_relevant.unwrap_or(false)
}
Expand Down Expand Up @@ -307,7 +346,7 @@ impl<'a> AttributeView<'a> {

fn write_examples<Out: Write>(&self, out: &mut Out) -> Result<(), Error> {
match &self.attribute.examples {
Some(examples) => write_examples_string(out, examples),
Some(examples) => write_examples_string(out, examples, self.is_array()),
None =>
// Enums can pull examples from the enum if not otherwise specified.
{
Expand Down

0 comments on commit 79b7ec1

Please sign in to comment.