Skip to content

Commit

Permalink
support ignoring alias fields from trace registry
Browse files Browse the repository at this point in the history
  • Loading branch information
ibalajiarun committed Dec 2, 2023
1 parent 1c88912 commit aa6c8cf
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 18 deletions.
45 changes: 31 additions & 14 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion serde-generate/Cargo.toml
Expand Up @@ -19,7 +19,7 @@ exclude = [
heck = "0.3.2"
include_dir = "0.6.0"
maplit = "1.0.2"
serde = { version = "1.0.126", features = ["derive"] }
serde = { version = "1.0.193", features = ["derive"] }
serde_bytes = "0.11.5"
serde_yaml = "0.8.17"
structopt = "0.3.21"
Expand Down
2 changes: 1 addition & 1 deletion serde-generate/src/rust.rs
Expand Up @@ -243,7 +243,7 @@ where
Option(format) => format!("Option<{}>", Self::quote_type(format, known_sizes)),
Seq(format) => format!("Vec<{}>", Self::quote_type(format, None)),
Map { key, value } => format!(
"Map<{}, {}>",
"std::collections::BTreeMap<{}, {}>",
Self::quote_type(key, None),
Self::quote_type(value, None)
),
Expand Down
2 changes: 1 addition & 1 deletion serde-reflection/Cargo.toml
Expand Up @@ -17,7 +17,7 @@ exclude = [

[dependencies]
thiserror = "1.0.25"
serde = { version = "1.0.126", features = ["derive"] }
serde = { version = "1.0.193", features = ["derive"] }
once_cell = "1.7.2"

[dev-dependencies]
Expand Down
59 changes: 58 additions & 1 deletion serde-reflection/src/trace.rs
Expand Up @@ -10,7 +10,10 @@ use crate::{
};
use once_cell::sync::Lazy;
use serde::{de::DeserializeSeed, Deserialize, Serialize};
use std::collections::{BTreeMap, BTreeSet};
use std::{
collections::{BTreeMap, BTreeSet},
ops::Deref,
};

/// A map of container formats.
pub type Registry = BTreeMap<String, ContainerFormat>;
Expand Down Expand Up @@ -285,6 +288,60 @@ impl Tracer {
self.record_container(samples, name, format, value, false)
}

/// Removes aliases for a field in a container from the registry.
///
/// The serde doesn't differentiate between alias names from field names so
/// this is a way to inform the registry of aliases of a particular field in a
/// container.
pub fn ignore_aliases(
&mut self,
container_name: &'static str,
aliases: &[&'static str],
) -> Result<()> {
let container_format = match self.registry.get_mut(container_name) {
None => {
return Err(Error::Custom(format!(
"cannot alias. container not found: {}",
container_name
)))
}
Some(container_format) => container_format,
};
match container_format {
ContainerFormat::Struct(named_formats) => {
let (non_alias_formats, alias_formats): (Vec<_>, Vec<_>) = named_formats
.iter()
.cloned()
.partition(|format| !aliases.contains(&format.name.deref()));

if alias_formats.len() != aliases.len() {
return Err(Error::Custom(format!(
"cannot ignore alias. not all aliases are found in container: {:?}",
aliases
)));
}

for alias_format in alias_formats {
if !alias_format.value.is_unknown() {
return Err(Error::Custom(format!(
"cannot ignore alias. tracer registered value: {}",
alias_format.name
)));
}
}

*named_formats = non_alias_formats;
}
_ => {
return Err(Error::Custom(format!(
"cannot record alias for non-struct container: {}",
container_name
)))
}
}
Ok(())
}

pub(crate) fn get_sample<'de, 'a>(
&'a self,
samples: &'de Samples,
Expand Down
39 changes: 39 additions & 0 deletions serde-reflection/tests/serde.rs
Expand Up @@ -457,3 +457,42 @@ fn test_repeated_tracing() {
))))))
);
}

#[test]
fn test_trace_deserialization_with_alias_types() {
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
struct Foo {
#[serde(rename = "b", alias = "c")]
pub a: Vec<u8>,
}

let samples = Samples::new();
let mut tracer = Tracer::new(TracerConfig::default());

tracer.trace_type::<Foo>(&samples).unwrap();
assert_eq!(
tracer.registry().unwrap_err(),
Error::UnknownFormatInContainer("Foo".into()),
);

let mut tracer = Tracer::new(TracerConfig::default());

tracer.trace_type::<Foo>(&samples).unwrap();
tracer
.ignore_aliases(
"Foo",
&["c"],
)
.unwrap();

let registry = tracer.registry().unwrap();
assert_eq!(
*registry.get("Foo").unwrap(),
ContainerFormat::Struct(vec![
Named {
name: "b".into(),
value: Format::Seq(Box::new(Format::U8))
}
])
);
}

0 comments on commit aa6c8cf

Please sign in to comment.