Skip to main content

otell_core/
ids.rs

1use serde::{Deserialize, Serialize};
2
3use crate::error::{OtellError, Result};
4
5#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
6pub struct TraceId(String);
7
8#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
9pub struct SpanId(String);
10
11impl TraceId {
12    pub fn parse(input: &str) -> Result<Self> {
13        if input.len() != 32 || !input.chars().all(|c| c.is_ascii_hexdigit()) {
14            return Err(OtellError::Parse(format!("invalid trace id: {input}")));
15        }
16        Ok(Self(input.to_ascii_lowercase()))
17    }
18
19    pub fn as_str(&self) -> &str {
20        &self.0
21    }
22}
23
24impl SpanId {
25    pub fn parse(input: &str) -> Result<Self> {
26        if input.len() != 16 || !input.chars().all(|c| c.is_ascii_hexdigit()) {
27            return Err(OtellError::Parse(format!("invalid span id: {input}")));
28        }
29        Ok(Self(input.to_ascii_lowercase()))
30    }
31
32    pub fn as_str(&self) -> &str {
33        &self.0
34    }
35}
36
37#[cfg(test)]
38mod tests {
39    use super::*;
40
41    #[test]
42    fn parses_ids() {
43        let trace = TraceId::parse("4bf92f3577b34da6a3ce929d0e0e4736").unwrap();
44        let span = SpanId::parse("00f067aa0ba902b7").unwrap();
45        assert_eq!(trace.as_str(), "4bf92f3577b34da6a3ce929d0e0e4736");
46        assert_eq!(span.as_str(), "00f067aa0ba902b7");
47    }
48
49    #[test]
50    fn rejects_bad_ids() {
51        assert!(TraceId::parse("abc").is_err());
52        assert!(SpanId::parse("zzzzzzzzzzzzzzzz").is_err());
53    }
54}