From 6b40262587f26ee18e48294977d577d135a6a83f Mon Sep 17 00:00:00 2001 From: "Daniel Szoke (via Pi Coding Agent)" Date: Fri, 4 Sep 2026 14:39:15 +0200 Subject: [PATCH] ref(types): Move sampling types to dedicated module Move `SampleRand` and `InvalidSampleRandError` from `protocol/v7.rs` into a new private top-level `sampling` module, re-exported from the old `protocol::v7` path, so the public API is unchanged. This is primarily code motion without any behavioral changes; the only non-mechanical edits are the imports the new module needs (`serde`, `thiserror`, and some `std::fmt`/`std::str` items). This prepares the module for upcoming sampling work related to propagating the sampling seed (`sample_rand`) with traces. References [#735](https://github.com/getsentry/sentry-rust/issues/735) References [RUST-1](https://linear.app/getsentry/issue/RUST-1) --- sentry-types/src/lib.rs | 1 + sentry-types/src/protocol/v7.rs | 50 +---------------------------- sentry-types/src/sampling.rs | 56 +++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 49 deletions(-) create mode 100644 sentry-types/src/sampling.rs diff --git a/sentry-types/src/lib.rs b/sentry-types/src/lib.rs index 61e871cae..5548ffcf0 100644 --- a/sentry-types/src/lib.rs +++ b/sentry-types/src/lib.rs @@ -45,6 +45,7 @@ mod dsn; mod indexed_enum; mod project_id; pub mod protocol; +mod sampling; pub(crate) mod utils; pub use crate::auth::*; diff --git a/sentry-types/src/protocol/v7.rs b/sentry-types/src/protocol/v7.rs index f05394258..4ae277fb1 100644 --- a/sentry-types/src/protocol/v7.rs +++ b/sentry-types/src/protocol/v7.rs @@ -2440,55 +2440,7 @@ impl std::fmt::Display for OrganizationId { } } -/// A random number generated at the start of a trace by the head of trace SDK. -#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)] -pub struct SampleRand(f64); - -/// An error that indicates failure to construct a SampleRand. -#[derive(Debug, Error)] -pub enum InvalidSampleRandError { - /// Indicates that the given value cannot be converted to a f64 succesfully. - #[error("failed to parse f64: {0}")] - InvalidFloat(#[from] std::num::ParseFloatError), - - /// Indicates that the given float is outside of the valid range for a sample rand, that is the - /// half-open interval [0.0, 1.0). - #[error("sample rand value out of admissible interval [0.0, 1.0)")] - OutOfRange, -} - -impl TryFrom for SampleRand { - type Error = InvalidSampleRandError; - - fn try_from(value: f64) -> Result { - if !(0.0..1.0).contains(&value) { - return Err(InvalidSampleRandError::OutOfRange); - } - Ok(Self(value)) - } -} - -impl std::str::FromStr for SampleRand { - type Err = InvalidSampleRandError; - - fn from_str(s: &str) -> Result { - let x: f64 = s.parse().map_err(InvalidSampleRandError::InvalidFloat)?; - Self::try_from(x) - } -} - -impl std::fmt::Display for SampleRand { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - // Special case: "{:.6}" would round values greater than or equal to 0.9999995 to 1.0, - // as Rust uses [rounding half-to-even](https://doc.rust-lang.org/std/fmt/#precision). - // Round to 0.999999 instead to comply with spec. - if self.0 >= 0.9999995 { - write!(f, "0.999999") - } else { - write!(f, "{:.6}", self.0) - } - } -} +pub use crate::sampling::{InvalidSampleRandError, SampleRand}; /// The [Dynamic Sampling /// Context](https://develop.sentry.dev/sdk/telemetry/traces/dynamic-sampling-context/). diff --git a/sentry-types/src/sampling.rs b/sentry-types/src/sampling.rs new file mode 100644 index 000000000..1c71080d9 --- /dev/null +++ b/sentry-types/src/sampling.rs @@ -0,0 +1,56 @@ +//! Sampling-related types. + +use serde::{Deserialize, Serialize}; +use std::fmt::{Display, Formatter, Result as FmtResult}; +use std::str::FromStr; +use thiserror::Error; + +/// A random number generated at the start of a trace by the head of trace SDK. +#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)] +pub struct SampleRand(f64); + +/// An error that indicates failure to construct a SampleRand. +#[derive(Debug, Error)] +pub enum InvalidSampleRandError { + /// Indicates that the given value cannot be converted to a f64 succesfully. + #[error("failed to parse f64: {0}")] + InvalidFloat(#[from] std::num::ParseFloatError), + + /// Indicates that the given float is outside of the valid range for a sample rand, that is the + /// half-open interval [0.0, 1.0). + #[error("sample rand value out of admissible interval [0.0, 1.0)")] + OutOfRange, +} + +impl TryFrom for SampleRand { + type Error = InvalidSampleRandError; + + fn try_from(value: f64) -> Result { + if !(0.0..1.0).contains(&value) { + return Err(InvalidSampleRandError::OutOfRange); + } + Ok(Self(value)) + } +} + +impl FromStr for SampleRand { + type Err = InvalidSampleRandError; + + fn from_str(s: &str) -> Result { + let x: f64 = s.parse().map_err(InvalidSampleRandError::InvalidFloat)?; + Self::try_from(x) + } +} + +impl Display for SampleRand { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + // Special case: "{:.6}" would round values greater than or equal to 0.9999995 to 1.0, + // as Rust uses [rounding half-to-even](https://doc.rust-lang.org/std/fmt/#precision). + // Round to 0.999999 instead to comply with spec. + if self.0 >= 0.9999995 { + write!(f, "0.999999") + } else { + write!(f, "{:.6}", self.0) + } + } +}