Skip to main content

refining_length/
length.rs

1//! Traits for types that have length defined for their values.
2
3use core::ffi::CStr;
4
5/// Represents types that have length defined for their values.
6pub trait HasLength {
7    /// Returns the value length.
8    fn length(&self) -> usize;
9}
10
11// core
12
13impl HasLength for str {
14    fn length(&self) -> usize {
15        self.len()
16    }
17}
18
19impl<T> HasLength for [T] {
20    fn length(&self) -> usize {
21        self.len()
22    }
23}
24
25impl<T: HasLength + ?Sized> HasLength for &T {
26    fn length(&self) -> usize {
27        (*self).length()
28    }
29}
30
31impl HasLength for CStr {
32    fn length(&self) -> usize {
33        self.to_bytes().length()
34    }
35}
36
37#[cfg(any(feature = "std", feature = "alloc"))]
38mod std_or_alloc {
39    cfg_select! {
40        feature = "std" => {
41            use std::{
42                borrow::{Cow, ToOwned},
43                collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque},
44                ffi::CString,
45                rc::Rc,
46                sync::Arc,
47            };
48        }
49        feature = "alloc" => {
50            use alloc::{
51                borrow::{Cow, ToOwned},
52                boxed::Box,
53                collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque},
54                ffi::CString,
55                rc::Rc,
56                string::String,
57                sync::Arc,
58                vec::Vec,
59            };
60        }
61    }
62
63    use super::HasLength;
64
65    // prelude
66
67    impl<T: HasLength + ?Sized> HasLength for Box<T> {
68        fn length(&self) -> usize {
69            self.as_ref().length()
70        }
71    }
72
73    impl HasLength for String {
74        fn length(&self) -> usize {
75            self.len()
76        }
77    }
78
79    impl<T> HasLength for Vec<T> {
80        fn length(&self) -> usize {
81            self.len()
82        }
83    }
84
85    // C strings
86
87    impl HasLength for CString {
88        fn length(&self) -> usize {
89            self.to_bytes().length()
90        }
91    }
92
93    // clone-on-write
94
95    impl<T: ToOwned + HasLength + ?Sized> HasLength for Cow<'_, T> {
96        fn length(&self) -> usize {
97            self.as_ref().length()
98        }
99    }
100
101    // reference-counted
102
103    impl<T: HasLength + ?Sized> HasLength for Rc<T> {
104        fn length(&self) -> usize {
105            self.as_ref().length()
106        }
107    }
108
109    impl<T: HasLength + ?Sized> HasLength for Arc<T> {
110        fn length(&self) -> usize {
111            self.as_ref().length()
112        }
113    }
114
115    // collections
116
117    impl<K, V> HasLength for BTreeMap<K, V> {
118        fn length(&self) -> usize {
119            self.len()
120        }
121    }
122
123    impl<T> HasLength for BTreeSet<T> {
124        fn length(&self) -> usize {
125            self.len()
126        }
127    }
128
129    impl<T> HasLength for BinaryHeap<T> {
130        fn length(&self) -> usize {
131            self.len()
132        }
133    }
134
135    impl<T> HasLength for LinkedList<T> {
136        fn length(&self) -> usize {
137            self.len()
138        }
139    }
140
141    impl<T> HasLength for VecDeque<T> {
142        fn length(&self) -> usize {
143            self.len()
144        }
145    }
146}
147
148#[cfg(feature = "std")]
149mod std_only {
150    use std::{
151        collections::{HashMap, HashSet},
152        ffi::{OsStr, OsString},
153        path::{Path, PathBuf},
154    };
155
156    use super::HasLength;
157
158    // collections
159
160    impl<K, V, S> HasLength for HashMap<K, V, S> {
161        fn length(&self) -> usize {
162            self.len()
163        }
164    }
165
166    impl<T, S> HasLength for HashSet<T, S> {
167        fn length(&self) -> usize {
168            self.len()
169        }
170    }
171
172    // OS strings
173
174    impl HasLength for OsStr {
175        fn length(&self) -> usize {
176            self.len()
177        }
178    }
179
180    impl HasLength for OsString {
181        fn length(&self) -> usize {
182            self.len()
183        }
184    }
185
186    // paths (via underlying strings)
187
188    impl HasLength for Path {
189        fn length(&self) -> usize {
190            self.as_os_str().length()
191        }
192    }
193
194    impl HasLength for PathBuf {
195        fn length(&self) -> usize {
196            self.as_os_str().length()
197        }
198    }
199}