diff --git a/oximeter/impl/src/schema/codegen.rs b/oximeter/impl/src/schema/codegen.rs index 89c1da4ac5..013250487e 100644 --- a/oximeter/impl/src/schema/codegen.rs +++ b/oximeter/impl/src/schema/codegen.rs @@ -78,7 +78,9 @@ fn emit_target(schema: &TimeseriesSchema) -> TokenStream { fn fields_are_copyable<'a>( mut fields: impl Iterator, ) -> bool { - !fields.any(|field| field.field_type == FieldType::String) + // Do a positive match, to ensure new variants don't actually derive copy + // inappropriately. Better we clone, in that case. + fields.all(FieldSchema::is_copyable) } fn compute_extra_derives( diff --git a/oximeter/impl/src/schema/mod.rs b/oximeter/impl/src/schema/mod.rs index 49f2ccb4f7..15eaad2c65 100644 --- a/oximeter/impl/src/schema/mod.rs +++ b/oximeter/impl/src/schema/mod.rs @@ -54,6 +54,13 @@ pub struct FieldSchema { pub description: String, } +impl FieldSchema { + /// Return `true` if this field is copyable. + pub const fn is_copyable(&self) -> bool { + self.field_type.is_copyable() + } +} + /// The source from which a field is derived, the target or metric. #[derive( Clone, diff --git a/oximeter/impl/src/types.rs b/oximeter/impl/src/types.rs index 0a19bc1441..370557f7f7 100644 --- a/oximeter/impl/src/types.rs +++ b/oximeter/impl/src/types.rs @@ -63,6 +63,29 @@ pub enum FieldType { Bool, } +impl FieldType { + /// Return `true` if a field of this type is copyable. + /// + /// NOTE: This doesn't mean `self` is copyable, instead refering to a field + /// with this type. + pub const fn is_copyable(&self) -> bool { + match self { + FieldType::String => false, + FieldType::I8 + | FieldType::U8 + | FieldType::I16 + | FieldType::U16 + | FieldType::I32 + | FieldType::U32 + | FieldType::I64 + | FieldType::U64 + | FieldType::IpAddr + | FieldType::Uuid + | FieldType::Bool => true, + } + } +} + impl std::fmt::Display for FieldType { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{:?}", self)