1use super::*;
2use std::borrow::Borrow;
3use std::convert::TryInto;
4use std::fmt::{self, Debug};
5use std::iter::FromIterator;
6use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign};
7
8
9#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
11pub struct Channel(RangedU8<0, 63>);
12
13impl Channel {
14 pub fn new(number: u8) -> Channel {
18 assert!((1..=64).contains(&number), "channel number is out of range");
19 Channel::from_u8_index(number - 1)
20 }
21
22 pub fn as_usize(self) -> usize {
24 self.0.as_u8().into()
25 }
26
27 pub(crate) fn from_u8_index(raw: u8) -> Channel {
29 Channel(raw.try_into().expect("channel index out of range"))
30 }
31}
32
33impl Debug for Channel {
34 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
35 write!(f, "ch{:02}", self.0.as_u8() + 1)
36 }
37}
38
39
40#[derive(Clone, Copy, PartialEq)]
42pub struct ActiveChannels(u64);
43
44impl ActiveChannels {
45 pub const fn all() -> ActiveChannels {
46 ActiveChannels(u64::MAX)
47 }
48
49 pub const fn empty() -> ActiveChannels {
50 ActiveChannels(0)
51 }
52
53 pub fn new<C: Borrow<Channel>>(iter: impl IntoIterator<Item=C>) -> ActiveChannels {
54 iter.into_iter()
55 .map(|c| *c.borrow())
56 .collect()
57 }
58
59 pub fn iter(self) -> impl Iterator<Item=Channel> {
60 (0..=63)
61 .filter(move |chan| (self.0 & (1u64 << chan)) != 0)
62 .map(Channel::from_u8_index)
63 }
64
65 pub const fn count(self) -> usize {
66 #[allow(clippy::as_conversions)]
68 { self.0.count_ones() as usize }
69 }
70}
71
72impl BitAnd<ActiveChannels> for ActiveChannels {
73 type Output = ActiveChannels;
74 fn bitand(self, rhs: ActiveChannels) -> Self::Output {
75 ActiveChannels(self.0 & rhs.0)
76 }
77}
78
79impl BitAndAssign for ActiveChannels {
80 fn bitand_assign(&mut self, rhs: ActiveChannels) {
81 *self = *self & rhs;
82 }
83}
84
85impl BitOr<ActiveChannels> for ActiveChannels {
86 type Output = ActiveChannels;
87 fn bitor(self, rhs: ActiveChannels) -> Self::Output {
88 ActiveChannels(self.0 | rhs.0)
89 }
90}
91
92impl BitOrAssign for ActiveChannels {
93 fn bitor_assign(&mut self, rhs: ActiveChannels) {
94 *self = *self | rhs;
95 }
96}
97
98impl FromIterator<Channel> for ActiveChannels {
99 fn from_iter<I: IntoIterator<Item=Channel>>(iter: I) -> ActiveChannels {
100 ActiveChannels(
101 iter.into_iter()
102 .map(|chan| 1u64 << chan.as_usize())
103 .fold(0u64, u64::bitor)
104 )
105 }
106}
107
108impl Debug for ActiveChannels {
109 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
110 f.debug_list()
111 .entries(self.iter())
112 .finish()
113 }
114}