Coverage Report

Created: 2025-09-05 06:33

/rust/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.10/src/str_owned.rs
Line
Count
Source (jump to first uncovered line)
1
//! Common handling for types backed by `String` with enforcement of a
2
//! library-level length limitation i.e. `Length::max()`.
3
4
use crate::{
5
    referenced::OwnedToRef, BytesRef, DecodeValue, EncodeValue, Header, Length, Reader, Result,
6
    StrRef, Writer,
7
};
8
use alloc::string::String;
9
use core::str;
10
11
/// String newtype which respects the [`Length::max`] limit.
12
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
13
pub struct StrOwned {
14
    /// Inner value
15
    pub(crate) inner: String,
16
17
    /// Precomputed `Length` (avoids possible panicking conversions)
18
    pub(crate) length: Length,
19
}
20
21
impl StrOwned {
22
    /// Create a new [`StrOwned`], ensuring that the byte representation of
23
    /// the provided `str` value is shorter than `Length::max()`.
24
0
    pub fn new(s: String) -> Result<Self> {
25
0
        let length = Length::try_from(s.as_bytes().len())?;
26
27
0
        Ok(Self { inner: s, length })
28
0
    }
29
30
    /// Parse a [`String`] from UTF-8 encoded bytes.
31
0
    pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
32
0
        Ok(Self {
33
0
            inner: String::from_utf8(bytes.to_vec())?,
34
0
            length: Length::try_from(bytes.len())?,
35
        })
36
0
    }
37
38
    /// Borrow the inner `str`
39
0
    pub fn as_str(&self) -> &str {
40
0
        &self.inner
41
0
    }
42
43
    /// Borrow the inner byte slice
44
0
    pub fn as_bytes(&self) -> &[u8] {
45
0
        self.inner.as_bytes()
46
0
    }
47
48
    /// Get the [`Length`] of this [`StrOwned`]
49
0
    pub fn len(&self) -> Length {
50
0
        self.length
51
0
    }
52
53
    /// Is this [`StrOwned`] empty?
54
0
    pub fn is_empty(&self) -> bool {
55
0
        self.len() == Length::ZERO
56
0
    }
57
}
58
59
impl AsRef<str> for StrOwned {
60
0
    fn as_ref(&self) -> &str {
61
0
        self.as_str()
62
0
    }
63
}
64
65
impl AsRef<[u8]> for StrOwned {
66
0
    fn as_ref(&self) -> &[u8] {
67
0
        self.as_bytes()
68
0
    }
69
}
70
71
impl<'a> DecodeValue<'a> for StrOwned {
72
0
    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
73
0
        Self::from_bytes(BytesRef::decode_value(reader, header)?.as_slice())
74
0
    }
75
}
76
77
impl EncodeValue for StrOwned {
78
0
    fn value_len(&self) -> Result<Length> {
79
0
        Ok(self.length)
80
0
    }
81
82
0
    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
83
0
        writer.write(self.as_ref())
84
0
    }
85
}
86
87
impl From<StrRef<'_>> for StrOwned {
88
0
    fn from(s: StrRef<'_>) -> StrOwned {
89
0
        Self {
90
0
            inner: String::from(s.inner),
91
0
            length: s.length,
92
0
        }
93
0
    }
94
}
95
96
impl OwnedToRef for StrOwned {
97
    type Borrowed<'a> = StrRef<'a>;
98
0
    fn owned_to_ref(&self) -> Self::Borrowed<'_> {
99
0
        StrRef {
100
0
            length: self.length,
101
0
            inner: self.inner.as_ref(),
102
0
        }
103
0
    }
104
}