Skip to content

Commit

Permalink
Implement Display on Baggage
Browse files Browse the repository at this point in the history
  • Loading branch information
wperron committed Nov 25, 2022
1 parent 6078e32 commit bf623d9
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
1 change: 1 addition & 0 deletions opentelemetry-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ once_cell = "1.12.0"
pin-project-lite = { version = "0.2", optional = true }
thiserror = "1"
tokio-stream = { version = "0.1", optional = true }
urlencoding = "2.1.2"

[package.metadata.docs.rs]
all-features = true
Expand Down
76 changes: 76 additions & 0 deletions opentelemetry-api/src/baggage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
use crate::{Context, Key, KeyValue, Value};
use once_cell::sync::Lazy;
use std::collections::{hash_map, HashMap};
use std::fmt;
use std::iter::FromIterator;
use urlencoding::encode;
// use urlencoding::encode;

static DEFAULT_BAGGAGE: Lazy<Baggage> = Lazy::new(Baggage::default);

Expand Down Expand Up @@ -280,6 +283,26 @@ impl FromIterator<KeyValueMetadata> for Baggage {
}
}

impl fmt::Display for Baggage {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut v: Vec<String> = self
.into_iter()
.map(|(k, v)| {
let mut val = encode(&v.0.as_str()).to_string();
if !v.1.as_str().is_empty() {
val.push_str(format!(";{}", v.1.as_str()).as_str())
}

format!("{}={}", k, val)
})
.collect();

v.sort();
let s = v.join(",");
Ok(write!(f, "{}", s)?)
}
}

/// Methods for sorting and retrieving baggage data in a context.
pub trait BaggageExt {
/// Returns a clone of the given context with the included name/value pairs.
Expand Down Expand Up @@ -397,6 +420,12 @@ impl From<&str> for BaggageMetadata {
}
}

impl fmt::Display for BaggageMetadata {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Ok(write!(f, "{}", self.as_str())?)
}
}

/// [`Baggage`] name/value pairs with their associated metadata.
#[derive(Clone, Debug, PartialEq)]
pub struct KeyValueMetadata {
Expand Down Expand Up @@ -436,6 +465,8 @@ impl From<KeyValue> for KeyValueMetadata {

#[cfg(test)]
mod tests {
use crate::StringValue;

use super::*;

#[test]
Expand Down Expand Up @@ -494,4 +525,49 @@ mod tests {
let baggage = data.into_iter().collect::<Baggage>();
assert_eq!(baggage.len(), 3)
}

#[test]
fn serialize_baggage_as_string() {
// Empty baggage
let b = Baggage::default();
assert_eq!("", b.to_string());

// "single member empty value no properties"
let mut b = Baggage::default();
b.insert("foo", StringValue::from(""));
assert_eq!("foo=", b.to_string());

// "single member no properties"
let mut b = Baggage::default();
b.insert("foo", StringValue::from("1"));
assert_eq!("foo=1", b.to_string());

// "URL encoded value"
let mut b = Baggage::default();
b.insert("foo", StringValue::from("1=1"));
assert_eq!("foo=1%3D1", b.to_string());

// "single member empty value with properties"
let mut b = Baggage::default();
b.insert_with_metadata(
"foo",
StringValue::from(""),
BaggageMetadata::from("red;state=on"),
);
assert_eq!("foo=;red;state=on", b.to_string());

// "single member with properties"
let mut b = Baggage::default();
b.insert_with_metadata("foo", StringValue::from("1"), "red;state=on;z=z=z");
assert_eq!("foo=1;red;state=on;z=z=z", b.to_string());

// "two members with properties"
let mut b = Baggage::default();
b.insert_with_metadata("foo", StringValue::from("1"), "red;state=on");
b.insert_with_metadata("bar", StringValue::from("2"), "yellow");
assert_eq!("bar=2;yellow,foo=1;red;state=on", b.to_string());

// assert it implements Display
let _ = format!("{}", b);
}
}

0 comments on commit bf623d9

Please sign in to comment.