gpiod_core/
values.rs

1use crate::{invalid_input, BitId, Error, Result};
2use std::{fmt, str};
3
4/// Value bits and mask
5pub type Bits = u64;
6
7/// Maximum number of values which can be get or set per time
8pub const MAX_VALUES: usize = core::mem::size_of::<Bits>() * 8;
9
10/// Maximum number of bits which can be get or set per time
11pub const MAX_BITS: BitId = MAX_VALUES as _;
12
13/// Default values representation
14pub type Values = Masked<Bits>;
15
16/// Something that can be used to get GPIO line values
17pub trait AsValues {
18    //// Number of bits
19    fn bits(&self) -> BitId;
20
21    /// Get the value of specific bit identified by offset
22    ///
23    /// If bit is out of range (0..bits) or not masked then None should be returned.
24    fn get(&self, id: BitId) -> Option<bool>;
25
26    /// Copy values to another variable
27    fn copy_into<T: AsValuesMut>(&self, other: &mut T) {
28        for id in 0..self.bits().min(other.bits()) {
29            other.set(id, self.get(id));
30        }
31    }
32
33    /// Convert to another representation
34    fn convert<T: AsValuesMut + Default>(&self) -> T {
35        let mut other = T::default();
36        self.copy_into(&mut other);
37        other
38    }
39}
40
41/// Something that can be used to get and set GPIO line values
42pub trait AsValuesMut: AsValues {
43    /// Set the value of specific bit identified by offset
44    ///
45    /// If bit if out of range (0..bits) then nothing should be set.
46    fn set(&mut self, id: BitId, val: Option<bool>);
47
48    /// Change the value of specific bit identified by offset
49    ///
50    /// If bit if out of range (0..bits) then nothing will be changed.
51    fn with(mut self, id: BitId, val: Option<bool>) -> Self
52    where
53        Self: Sized,
54    {
55        self.set(id, val);
56        self
57    }
58
59    /// Copy values to another variable
60    fn copy_from<T: AsValues>(&mut self, other: &T) {
61        for id in 0..self.bits().min(other.bits()) {
62            self.set(id, other.get(id));
63        }
64    }
65
66    /// Fill values in range
67    fn fill<R: Iterator<Item = BitId>>(&mut self, range: R, val: Option<bool>) {
68        for id in range {
69            self.set(id, val);
70        }
71    }
72
73    /// Truncate mask
74    fn truncate(&mut self, len: BitId) {
75        for id in len..self.bits() {
76            self.set(id, None);
77        }
78    }
79}
80
81impl<T: AsValues> AsValues for &T {
82    fn bits(&self) -> BitId {
83        (**self).bits()
84    }
85
86    fn get(&self, id: BitId) -> Option<bool> {
87        (**self).get(id)
88    }
89}
90
91impl<T: AsValues> AsValues for &mut T {
92    fn bits(&self) -> BitId {
93        (**self).bits()
94    }
95
96    fn get(&self, id: BitId) -> Option<bool> {
97        (**self).get(id)
98    }
99}
100
101impl<T: AsValuesMut> AsValuesMut for &mut T {
102    fn set(&mut self, id: BitId, val: Option<bool>) {
103        (**self).set(id, val)
104    }
105}
106
107/// Line values with mask
108#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
109#[repr(C)]
110pub struct Masked<Bits> {
111    /// Logic values of lines
112    pub bits: Bits,
113
114    /// Mask of lines to get or set
115    pub mask: Bits,
116}
117
118macro_rules! as_values {
119    ($($type:ty,)*) => {
120        $(
121            impl AsValues for $type {
122                fn bits(&self) -> BitId {
123                    (core::mem::size_of::<$type>() * 8) as _
124                }
125
126                fn get(&self, id: BitId) -> Option<bool> {
127                    if id >= (core::mem::size_of::<$type>() * 8) as _ {
128                        return None;
129                    }
130
131                    Some(self & (1 << id) != 0)
132                }
133            }
134
135            impl AsValuesMut for $type {
136                fn set(&mut self, id: BitId, val: Option<bool>) {
137                    if id >= (core::mem::size_of::<$type>() * 8) as _ {
138                        return;
139                    }
140
141                    let mask = (1 as $type) << id;
142
143                    if let Some(true) = val {
144                        *self |= mask;
145                    } else {
146                        *self &= !mask;
147                    }
148                }
149            }
150
151            impl AsValues for Masked<$type> {
152                fn bits(&self) -> BitId {
153                    (core::mem::size_of::<$type>() * 8) as _
154                }
155
156                fn get(&self, id: BitId) -> Option<bool> {
157                    if id >= (core::mem::size_of::<$type>() * 8) as _ {
158                        return None;
159                    }
160
161                    let mask = (1 as $type) << id;
162
163                    if self.mask & mask == 0 {
164                        return None;
165                    }
166
167                    Some(self.bits & mask != 0)
168                }
169            }
170
171            impl AsValuesMut for Masked<$type> {
172                fn set(&mut self, id: BitId, val: Option<bool>) {
173                    if id >= (core::mem::size_of::<$type>() * 8) as _ {
174                        return;
175                    }
176
177                    let mask = (1 as $type) << id;
178
179                    if let Some(val) = val {
180                        self.mask |= mask;
181
182                        if val {
183                            self.bits |= mask;
184                        } else {
185                            self.bits &= !mask;
186                        }
187                    } else {
188                        let mask = !mask;
189
190                        self.mask &= mask;
191                        self.bits &= mask;
192                    }
193                }
194            }
195
196            impl From<$type> for Masked<$type> {
197                fn from(bits: $type) -> Self {
198                    Self {
199                        bits: bits as _,
200                        mask: <$type>::MAX as _,
201                    }
202                }
203            }
204
205            impl From<Masked<$type>> for $type {
206                fn from(values: Masked<$type>) -> Self {
207                    (values.bits & values.mask) as _
208                }
209            }
210
211            impl fmt::Binary for Masked<$type> {
212                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
213                    use fmt::Write;
214
215                    let max = (core::mem::size_of::<$type>() * 8) as BitId;
216                    let len = (max - (self.mask & self.bits).leading_zeros() as BitId).max(1);
217                    let fill = f.width().map(|width| {
218                        let width = if f.alternate() {
219                            width - 2
220                        } else {
221                            width
222                        };
223                        if width > len as _ {
224                            width - len as usize
225                        } else {
226                            0
227                        }
228                    }).unwrap_or(0);
229                    let (fill_before, fill_after) = match f.align() {
230                        Some(fmt::Alignment::Left) => (0, fill),
231                        Some(fmt::Alignment::Right) | None => (fill, 0),
232                        Some(fmt::Alignment::Center) => (fill - fill / 2, fill / 2),
233                    };
234                    let fill_char = f.fill();
235                    if f.alternate() {
236                        f.write_str("0b")?;
237                    }
238                    for _ in 0..fill_before {
239                        f.write_char(fill_char)?;
240                    }
241                    for i in (0..len).rev() {
242                        f.write_char(match self.get(i) {
243                            Some(true) => '1',
244                            Some(false) => '0',
245                            None => 'x',
246                        })?;
247                    }
248                    for _ in 0..fill_after {
249                        f.write_char(fill_char)?;
250                    }
251                    Ok(())
252                }
253            }
254
255            impl fmt::Display for Masked<$type> {
256                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
257                    fmt::Binary::fmt(self, f)
258                }
259            }
260
261            impl str::FromStr for Masked<$type> {
262                type Err = Error;
263
264                fn from_str(s: &str) -> Result<Self> {
265                    let s = s.strip_prefix("0b").unwrap_or(s);
266                    let mut i = s.len() as BitId;
267                    if i > (core::mem::size_of::<$type>() * 8) as _ {
268                        return Err(invalid_input("Too many line values"));
269                    }
270                    let mut r = Self::default();
271                    for c in s.chars() {
272                        i -= 1;
273                        match c {
274                            '1' => {
275                                let b = 1 << i;
276                                r.bits |= b;
277                                r.mask |= b;
278                            }
279                            '0' => {
280                                let b = 1 << i;
281                                r.mask |= b;
282                            }
283                            'x' => {}
284                            _ => return Err(invalid_input("Unexpected char in line value")),
285                        }
286                    }
287                    Ok(r)
288                }
289            }
290
291        )*
292    };
293}
294
295as_values! {
296    u8,
297    u16,
298    u32,
299    u64,
300}
301
302impl AsValues for [bool] {
303    fn bits(&self) -> BitId {
304        self.len() as _
305    }
306
307    fn get(&self, id: BitId) -> Option<bool> {
308        if id >= self.len() as _ {
309            return None;
310        }
311
312        Some(self[id as usize])
313    }
314}
315
316impl AsValuesMut for [bool] {
317    fn set(&mut self, id: BitId, val: Option<bool>) {
318        if id >= self.len() as _ {
319            return;
320        }
321
322        if let Some(val) = val {
323            self[id as usize] = val;
324        }
325    }
326}
327
328impl AsValues for Vec<bool> {
329    fn bits(&self) -> BitId {
330        self.len() as _
331    }
332
333    fn get(&self, id: BitId) -> Option<bool> {
334        if id >= self.len() as _ {
335            return None;
336        }
337
338        Some(self[id as usize])
339    }
340}
341
342impl AsValuesMut for Vec<bool> {
343    fn set(&mut self, id: BitId, val: Option<bool>) {
344        if id >= self.len() as _ {
345            return;
346        }
347
348        if let Some(val) = val {
349            self[id as usize] = val;
350        }
351    }
352}
353
354impl<const LEN: usize> AsValues for [bool; LEN] {
355    fn bits(&self) -> BitId {
356        LEN as _
357    }
358
359    fn get(&self, id: BitId) -> Option<bool> {
360        if id >= LEN as _ {
361            return None;
362        }
363
364        Some(self[id as usize])
365    }
366}
367
368impl<const LEN: usize> AsValuesMut for [bool; LEN] {
369    fn set(&mut self, id: BitId, val: Option<bool>) {
370        if id >= LEN as _ {
371            return;
372        }
373
374        if let Some(val) = val {
375            self[id as usize] = val;
376        }
377    }
378}
379
380impl AsValues for [Option<bool>] {
381    fn bits(&self) -> BitId {
382        self.len() as _
383    }
384
385    fn get(&self, id: BitId) -> Option<bool> {
386        if id >= self.len() as _ {
387            return None;
388        }
389
390        self[id as usize]
391    }
392}
393
394impl AsValuesMut for [Option<bool>] {
395    fn set(&mut self, id: BitId, val: Option<bool>) {
396        if id >= self.len() as _ {
397            return;
398        }
399
400        self[id as usize] = val;
401    }
402}
403
404impl AsValues for Vec<Option<bool>> {
405    fn bits(&self) -> BitId {
406        self.len() as _
407    }
408
409    fn get(&self, id: BitId) -> Option<bool> {
410        if id >= self.len() as _ {
411            return None;
412        }
413
414        self[id as usize]
415    }
416}
417
418impl AsValuesMut for Vec<Option<bool>> {
419    fn set(&mut self, id: BitId, val: Option<bool>) {
420        if id >= self.len() as _ {
421            return;
422        }
423
424        self[id as usize] = val;
425    }
426}
427
428impl<const LEN: usize> AsValues for [Option<bool>; LEN] {
429    fn bits(&self) -> BitId {
430        LEN as _
431    }
432
433    fn get(&self, id: BitId) -> Option<bool> {
434        if id >= LEN as _ {
435            return None;
436        }
437
438        self[id as usize]
439    }
440}
441
442impl<const LEN: usize> AsValuesMut for [Option<bool>; LEN] {
443    fn set(&mut self, id: BitId, val: Option<bool>) {
444        if id >= LEN as _ {
445            return;
446        }
447
448        self[id as usize] = val;
449    }
450}
451
452#[cfg(test)]
453mod test {
454    use super::*;
455
456    #[test]
457    fn format_masked() {
458        assert_eq!(Masked::from(0b1000u8).to_string(), "1000");
459
460        assert_eq!(
461            Values {
462                bits: 0b1000,
463                mask: 0b1111,
464            }
465            .to_string(),
466            "1000"
467        );
468
469        assert_eq!(
470            Values {
471                bits: 0b0011,
472                mask: 0b0111,
473            }
474            .to_string(),
475            "11"
476        );
477
478        assert_eq!(
479            Values {
480                bits: 0b0011,
481                mask: 0b1111,
482            }
483            .to_string(),
484            "11"
485        );
486
487        assert_eq!(
488            Values {
489                bits: 0b11000,
490                mask: 0b00011,
491            }
492            .to_string(),
493            "0"
494        );
495
496        assert_eq!(
497            Values {
498                bits: 0b100001,
499                mask: 0b110011,
500            }
501            .to_string(),
502            "10xx01"
503        );
504    }
505
506    #[test]
507    fn format_masked_advanced() {
508        assert_eq!(format!("{:#}", Masked::from(0b1000u8)), "0b1000");
509
510        assert_eq!(format!("{:#08b}", 0b1000u8), "0b001000");
511
512        //assert_eq!(format!("{:#08b}", Masked::from(0b1000u8)), "0b001000");
513
514        assert_eq!(format!("{:11}", Masked::from(0b1000u8)), "       1000");
515
516        assert_eq!(format!("{:-<11}", Masked::from(0b1000u8)), "1000-------");
517
518        assert_eq!(format!("{:->11}", Masked::from(0b1000u8)), "-------1000");
519
520        assert_eq!(format!("{:-^11}", Masked::from(0b1000u8)), "----1000---");
521    }
522
523    #[test]
524    fn parse_masked() {
525        assert_eq!(
526            "0110".parse::<Values>().unwrap(),
527            Values {
528                bits: 0b0110,
529                mask: 0b1111,
530            }
531        );
532
533        assert_eq!(
534            "00110".parse::<Values>().unwrap(),
535            Values {
536                bits: 0b00110,
537                mask: 0b11111,
538            }
539        );
540
541        assert_eq!(
542            "0b10101".parse::<Values>().unwrap(),
543            Values {
544                bits: 0b10101,
545                mask: 0b11111,
546            }
547        );
548
549        assert_eq!(
550            "1x10x".parse::<Values>().unwrap(),
551            Values {
552                bits: 0b10100,
553                mask: 0b10110,
554            }
555        );
556
557        assert_eq!(
558            "xx0x010".parse::<Values>().unwrap(),
559            Values {
560                bits: 0b00010,
561                mask: 0b10111,
562            }
563        );
564
565        assert_eq!(
566            "0bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
567                .parse::<Values>()
568                .unwrap(),
569            Values::default()
570        );
571
572        assert_eq!(
573            "0b1111111111111111111111111111111111111111111111111111111111111111"
574                .parse::<Values>()
575                .unwrap(),
576            Values {
577                bits: Bits::MAX,
578                mask: Bits::MAX,
579            }
580        );
581
582        assert_eq!(
583            "0b0000000000000000000000000000000000000000000000000000000000000000"
584                .parse::<Values>()
585                .unwrap(),
586            Values {
587                bits: 0,
588                mask: Bits::MAX,
589            }
590        );
591
592        assert!(
593            "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
594                .parse::<Values>()
595                .is_err()
596        );
597
598        assert!("0b10xy".parse::<Values>().is_err());
599    }
600}