zipkin_types/
span_id.rs

1//  Copyright 2017 Palantir Technologies, Inc.
2//
3//  Licensed under the Apache License, Version 2.0 (the "License");
4//  you may not use this file except in compliance with the License.
5//  You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9//  Unless required by applicable law or agreed to in writing, software
10//  distributed under the License is distributed on an "AS IS" BASIS,
11//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//  See the License for the specific language governing permissions and
13//  limitations under the License.
14
15//! Span IDs.
16use data_encoding::{DecodeError, HEXLOWER_PERMISSIVE};
17use std::error::Error;
18use std::fmt;
19use std::str::FromStr;
20
21/// The ID of a span.
22///
23/// Span IDs are 8 bytes, and are serialized as hexadecimal strings.
24#[derive(Copy, Clone, Debug, PartialEq, Eq)]
25pub struct SpanId {
26    buf: [u8; 8],
27}
28
29impl FromStr for SpanId {
30    type Err = SpanIdParseError;
31
32    fn from_str(s: &str) -> Result<SpanId, SpanIdParseError> {
33        let mut buf = [0; 8];
34        match HEXLOWER_PERMISSIVE.decode_len(s.len()) {
35            Ok(8) => {
36                HEXLOWER_PERMISSIVE
37                    .decode_mut(s.as_bytes(), &mut buf)
38                    .map_err(|e| SpanIdParseError(Some(e.error)))?;
39            }
40            _ => return Err(SpanIdParseError(None)),
41        }
42
43        Ok(SpanId { buf })
44    }
45}
46
47impl fmt::Display for SpanId {
48    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
49        for b in self.bytes() {
50            write!(fmt, "{:02x}", b)?;
51        }
52        Ok(())
53    }
54}
55
56#[cfg(feature = "serde")]
57mod serde {
58    use crate::span_id::SpanId;
59    use serde::de::{Error, Unexpected, Visitor};
60    use serde::{Deserialize, Deserializer, Serialize, Serializer};
61    use std::fmt;
62
63    impl Serialize for SpanId {
64        fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
65        where
66            S: Serializer,
67        {
68            s.collect_str(self)
69        }
70    }
71
72    impl<'de> Deserialize<'de> for SpanId {
73        fn deserialize<D>(d: D) -> Result<SpanId, D::Error>
74        where
75            D: Deserializer<'de>,
76        {
77            d.deserialize_str(V)
78        }
79    }
80
81    struct V;
82
83    impl<'de> Visitor<'de> for V {
84        type Value = SpanId;
85
86        fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
87            fmt.write_str("a hex-encoded span ID")
88        }
89
90        fn visit_str<E>(self, v: &str) -> Result<SpanId, E>
91        where
92            E: Error,
93        {
94            v.parse()
95                .map_err(|_| Error::invalid_value(Unexpected::Str(v), &self))
96        }
97    }
98}
99
100impl SpanId {
101    /// Returns the bytes of the span ID.
102    #[inline]
103    pub fn bytes(&self) -> &[u8] {
104        &self.buf
105    }
106}
107
108impl From<[u8; 8]> for SpanId {
109    #[inline]
110    fn from(bytes: [u8; 8]) -> SpanId {
111        SpanId { buf: bytes }
112    }
113}
114
115/// The error returned when parsing a `SpanId` from a string.
116#[derive(Debug)]
117pub struct SpanIdParseError(Option<DecodeError>);
118
119impl fmt::Display for SpanIdParseError {
120    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
121        fmt.write_str("error parsing span: ")?;
122        match self.0 {
123            Some(ref err) => write!(fmt, "{}", err),
124            None => fmt.write_str("invalid length"),
125        }
126    }
127}
128
129impl Error for SpanIdParseError {
130    fn source(&self) -> Option<&(dyn Error + 'static)> {
131        self.0.as_ref().map(|e| e as _)
132    }
133}