1use super::*;
7
8#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
12pub struct DbScale {
13 pub min: i32,
16 pub step: u16,
19 pub mute_avail: bool,
22}
23
24pub const CTL_VALUE_MUTE: i32 = SNDRV_CTL_TLVD_DB_GAIN_MUTE;
27
28pub const DB_VALUE_MULTIPLIER: i32 = 100;
30
31impl DbScale {
32 const VALUE_COUNT: usize = 2;
33}
34
35impl<'a> TlvData<'a> for DbScale {
36 fn value_type(&self) -> u32 {
37 SNDRV_CTL_TLVT_DB_SCALE
38 }
39
40 fn value_length(&self) -> usize {
41 Self::VALUE_COUNT
42 }
43
44 fn value(&self) -> Vec<u32> {
45 let mut raw = Vec::new();
46 raw.push(self.min as u32);
47 raw.push(self.step as u32);
48 if self.mute_avail {
49 raw[1] |= SNDRV_CTL_TLVD_DB_SCALE_MUTE;
50 }
51 raw
52 }
53}
54
55const TYPES_FOR_DB_SCALE: &'static [u32] = &[SNDRV_CTL_TLVT_DB_SCALE];
56
57impl std::convert::TryFrom<&[u32]> for DbScale {
58 type Error = TlvDecodeError;
59
60 fn try_from(raw: &[u32]) -> Result<Self, Self::Error> {
61 if raw.len() < 2 {
63 Err(Self::Error::new(TlvDecodeErrorCtx::Length(raw.len(), 2), 0))
64 } else if raw[0] != SNDRV_CTL_TLVT_DB_SCALE {
66 Err(Self::Error::new(
67 TlvDecodeErrorCtx::ValueType(raw[0], TYPES_FOR_DB_SCALE),
68 0,
69 ))
70 } else {
71 let value_length = (raw[1] / 4) as usize;
73 let value = &raw[2..];
74 if value.len() < value_length {
75 Err(Self::Error::new(
76 TlvDecodeErrorCtx::ValueLength(value_length, value.len()),
77 1,
78 ))
79 } else {
80 Ok(Self {
82 min: value[0] as i32,
83 step: (value[1] & SNDRV_CTL_TLVD_DB_SCALE_MASK) as u16,
84 mute_avail: value[1] & SNDRV_CTL_TLVD_DB_SCALE_MUTE > 0,
85 })
86 }
87 }
88 }
89}
90
91impl From<&DbScale> for Vec<u32> {
92 fn from(data: &DbScale) -> Self {
93 let mut raw = Vec::new();
94 raw.push(data.value_type());
95 raw.push(4 * data.value_length() as u32);
96 raw.append(&mut data.value());
97 raw
98 }
99}
100
101impl From<DbScale> for Vec<u32> {
102 fn from(data: DbScale) -> Self {
103 (&data).into()
104 }
105}
106
107#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
116pub struct DbInterval {
117 pub min: i32,
120 pub max: i32,
123 pub linear: bool,
130 pub mute_avail: bool,
133}
134
135impl DbInterval {
136 const VALUE_COUNT: usize = 2;
137}
138
139impl<'a> TlvData<'a> for DbInterval {
140 fn value_type(&self) -> u32 {
141 if self.linear {
142 SNDRV_CTL_TLVT_DB_LINEAR
143 } else if self.mute_avail {
144 SNDRV_CTL_TLVT_DB_MINMAX_MUTE
145 } else {
146 SNDRV_CTL_TLVT_DB_MINMAX
147 }
148 }
149
150 fn value_length(&self) -> usize {
151 Self::VALUE_COUNT
152 }
153
154 fn value(&self) -> Vec<u32> {
155 vec![self.min as u32, self.max as u32]
156 }
157}
158
159const TYPES_FOR_DB_INTERVAL: &'static [u32] = &[
160 SNDRV_CTL_TLVT_DB_LINEAR,
161 SNDRV_CTL_TLVT_DB_MINMAX,
162 SNDRV_CTL_TLVT_DB_MINMAX_MUTE,
163];
164
165impl std::convert::TryFrom<&[u32]> for DbInterval {
166 type Error = TlvDecodeError;
167
168 fn try_from(raw: &[u32]) -> Result<Self, Self::Error> {
169 if raw.len() < 2 {
171 Err(Self::Error::new(TlvDecodeErrorCtx::Length(raw.len(), 2), 0))
172 } else {
173 let value_length = (raw[1] / 4) as usize;
175 let value = &raw[2..];
176 if value.len() < value_length || value.len() < Self::VALUE_COUNT {
177 Err(Self::Error::new(
178 TlvDecodeErrorCtx::ValueLength(value_length, value.len()),
179 1,
180 ))
181 } else {
182 match raw[0] {
184 SNDRV_CTL_TLVT_DB_LINEAR => Ok(Self {
185 min: value[0] as i32,
186 max: value[1] as i32,
187 linear: true,
188 mute_avail: true,
189 }),
190 SNDRV_CTL_TLVT_DB_MINMAX => Ok(Self {
191 min: value[0] as i32,
192 max: value[1] as i32,
193 linear: false,
194 mute_avail: false,
195 }),
196 SNDRV_CTL_TLVT_DB_MINMAX_MUTE => Ok(Self {
197 min: value[0] as i32,
198 max: value[1] as i32,
199 linear: false,
200 mute_avail: true,
201 }),
202 _ => Err(Self::Error::new(
203 TlvDecodeErrorCtx::ValueType(raw[0], TYPES_FOR_DB_INTERVAL),
204 0,
205 )),
206 }
207 }
208 }
209 }
210}
211
212impl From<&DbInterval> for Vec<u32> {
213 fn from(data: &DbInterval) -> Self {
214 let mut raw = Vec::new();
215 raw.push(data.value_type());
216 raw.push(4 * data.value_length() as u32);
217 raw.append(&mut data.value());
218 raw
219 }
220}
221
222impl From<DbInterval> for Vec<u32> {
223 fn from(data: DbInterval) -> Self {
224 (&data).into()
225 }
226}
227
228#[derive(Debug, Copy, Clone, PartialEq, Eq)]
231pub enum ChmapGenericPos {
232 Unknown,
233 NotAvailable,
234 Monaural,
235 FrontLeft,
236 FrontRight,
237 RearLeft,
238 RearRight,
239 FrontCenter,
240 LowFrequencyEffect,
241 SideLeft,
242 SideRight,
243 RearCenter,
244 FrontLeftCenter,
245 FrontRightCenter,
246 RearLeftCenter,
247 RearRightCenter,
248 FrontLeftWide,
249 FrontRightWide,
250 FrontLeftHigh,
251 FrontCenterHigh,
252 FrontRightHigh,
253 TopCenter,
254 TopFrontLeft,
255 TopFrontRight,
256 TopFrontCenter,
257 TopRearLeft,
258 TopRearRight,
259 TopRearCenter,
260 TopFrontLeftCenter,
261 TopFrontRightCenter,
262 TopSideLeft,
263 TopSideRight,
264 LeftLowFrequencyEffect,
265 RightLowFrequencyEffect,
266 BottomCenter,
267 BottomLeftCenter,
268 BottomRightCenter,
269 Reserved(u16),
270}
271
272impl Default for ChmapGenericPos {
273 fn default() -> Self {
274 Self::Unknown
275 }
276}
277
278impl std::convert::From<u16> for ChmapGenericPos {
279 fn from(val: u16) -> Self {
280 match val as u16 {
281 SNDRV_CHMAP_UNKNOWN => Self::Unknown,
282 SNDRV_CHMAP_NA => Self::NotAvailable,
283 SNDRV_CHMAP_MONO => Self::Monaural,
284 SNDRV_CHMAP_FL => Self::FrontLeft,
285 SNDRV_CHMAP_FR => Self::FrontRight,
286 SNDRV_CHMAP_RL => Self::RearLeft,
287 SNDRV_CHMAP_RR => Self::RearRight,
288 SNDRV_CHMAP_FC => Self::FrontCenter,
289 SNDRV_CHMAP_LFE => Self::LowFrequencyEffect,
290 SNDRV_CHMAP_SL => Self::SideLeft,
291 SNDRV_CHMAP_SR => Self::SideRight,
292 SNDRV_CHMAP_RC => Self::RearCenter,
293 SNDRV_CHMAP_FLC => Self::FrontLeftCenter,
294 SNDRV_CHMAP_FRC => Self::FrontRightCenter,
295 SNDRV_CHMAP_RLC => Self::RearLeftCenter,
296 SNDRV_CHMAP_RRC => Self::RearRightCenter,
297 SNDRV_CHMAP_FLW => Self::FrontLeftWide,
298 SNDRV_CHMAP_FRW => Self::FrontRightWide,
299 SNDRV_CHMAP_FLH => Self::FrontLeftHigh,
300 SNDRV_CHMAP_FCH => Self::FrontCenterHigh,
301 SNDRV_CHMAP_FRH => Self::FrontRightHigh,
302 SNDRV_CHMAP_TC => Self::TopCenter,
303 SNDRV_CHMAP_TFL => Self::TopFrontLeft,
304 SNDRV_CHMAP_TFR => Self::TopFrontRight,
305 SNDRV_CHMAP_TFC => Self::TopFrontCenter,
306 SNDRV_CHMAP_TRL => Self::TopRearLeft,
307 SNDRV_CHMAP_TRR => Self::TopRearRight,
308 SNDRV_CHMAP_TRC => Self::TopRearCenter,
309 SNDRV_CHMAP_TFLC => Self::TopFrontLeftCenter,
310 SNDRV_CHMAP_TFRC => Self::TopFrontRightCenter,
311 SNDRV_CHMAP_TSL => Self::TopSideLeft,
312 SNDRV_CHMAP_TSR => Self::TopSideRight,
313 SNDRV_CHMAP_LLFE => Self::LeftLowFrequencyEffect,
314 SNDRV_CHMAP_RLFE => Self::RightLowFrequencyEffect,
315 SNDRV_CHMAP_BC => Self::BottomCenter,
316 SNDRV_CHMAP_BLC => Self::BottomLeftCenter,
317 SNDRV_CHMAP_BRC => Self::BottomRightCenter,
318 _ => Self::Reserved(val),
319 }
320 }
321}
322
323impl From<ChmapGenericPos> for u16 {
324 fn from(code: ChmapGenericPos) -> Self {
325 match code {
326 ChmapGenericPos::Unknown => SNDRV_CHMAP_UNKNOWN,
327 ChmapGenericPos::NotAvailable => SNDRV_CHMAP_NA,
328 ChmapGenericPos::Monaural => SNDRV_CHMAP_MONO,
329 ChmapGenericPos::FrontLeft => SNDRV_CHMAP_FL,
330 ChmapGenericPos::FrontRight => SNDRV_CHMAP_FR,
331 ChmapGenericPos::RearLeft => SNDRV_CHMAP_RL,
332 ChmapGenericPos::RearRight => SNDRV_CHMAP_RR,
333 ChmapGenericPos::FrontCenter => SNDRV_CHMAP_FC,
334 ChmapGenericPos::LowFrequencyEffect => SNDRV_CHMAP_LFE,
335 ChmapGenericPos::SideLeft => SNDRV_CHMAP_SL,
336 ChmapGenericPos::SideRight => SNDRV_CHMAP_SR,
337 ChmapGenericPos::RearCenter => SNDRV_CHMAP_RC,
338 ChmapGenericPos::FrontLeftCenter => SNDRV_CHMAP_FLC,
339 ChmapGenericPos::FrontRightCenter => SNDRV_CHMAP_FRC,
340 ChmapGenericPos::RearLeftCenter => SNDRV_CHMAP_RLC,
341 ChmapGenericPos::RearRightCenter => SNDRV_CHMAP_RRC,
342 ChmapGenericPos::FrontLeftWide => SNDRV_CHMAP_FLW,
343 ChmapGenericPos::FrontRightWide => SNDRV_CHMAP_FRW,
344 ChmapGenericPos::FrontLeftHigh => SNDRV_CHMAP_FLH,
345 ChmapGenericPos::FrontCenterHigh => SNDRV_CHMAP_FCH,
346 ChmapGenericPos::FrontRightHigh => SNDRV_CHMAP_FRH,
347 ChmapGenericPos::TopCenter => SNDRV_CHMAP_TC,
348 ChmapGenericPos::TopFrontLeft => SNDRV_CHMAP_TFL,
349 ChmapGenericPos::TopFrontRight => SNDRV_CHMAP_TFR,
350 ChmapGenericPos::TopFrontCenter => SNDRV_CHMAP_TFC,
351 ChmapGenericPos::TopRearLeft => SNDRV_CHMAP_TRL,
352 ChmapGenericPos::TopRearRight => SNDRV_CHMAP_TRR,
353 ChmapGenericPos::TopRearCenter => SNDRV_CHMAP_TRC,
354 ChmapGenericPos::TopFrontLeftCenter => SNDRV_CHMAP_TFLC,
355 ChmapGenericPos::TopFrontRightCenter => SNDRV_CHMAP_TFRC,
356 ChmapGenericPos::TopSideLeft => SNDRV_CHMAP_TSL,
357 ChmapGenericPos::TopSideRight => SNDRV_CHMAP_TSR,
358 ChmapGenericPos::LeftLowFrequencyEffect => SNDRV_CHMAP_LLFE,
359 ChmapGenericPos::RightLowFrequencyEffect => SNDRV_CHMAP_RLFE,
360 ChmapGenericPos::BottomCenter => SNDRV_CHMAP_BC,
361 ChmapGenericPos::BottomLeftCenter => SNDRV_CHMAP_BLC,
362 ChmapGenericPos::BottomRightCenter => SNDRV_CHMAP_BRC,
363 ChmapGenericPos::Reserved(val) => val,
364 }
365 }
366}
367
368#[derive(Debug, Copy, Clone, PartialEq, Eq)]
370pub enum ChmapPos {
371 Generic(ChmapGenericPos),
373 Specific(u16),
376}
377
378impl Default for ChmapPos {
379 fn default() -> Self {
380 Self::Generic(Default::default())
381 }
382}
383
384#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
386pub struct ChmapEntry {
387 pub pos: ChmapPos,
389 pub phase_inverse: bool,
392}
393
394impl std::convert::From<u32> for ChmapEntry {
395 fn from(val: u32) -> Self {
396 let pos_val = (val & 0x0000ffff) as u16;
397 let phase_inverse = val & SNDRV_CHMAP_PHASE_INVERSE > 0;
398 let driver_spec = val & SNDRV_CHMAP_DRIVER_SPEC > 0;
399 let pos = if driver_spec {
400 ChmapPos::Specific(pos_val)
401 } else {
402 ChmapPos::Generic(ChmapGenericPos::from(pos_val))
403 };
404 ChmapEntry { pos, phase_inverse }
405 }
406}
407
408impl From<ChmapEntry> for u32 {
409 fn from(entry: ChmapEntry) -> Self {
410 let mut val = match entry.pos {
411 ChmapPos::Generic(p) => u16::from(p) as u32,
412 ChmapPos::Specific(p) => (p as u32) | SNDRV_CHMAP_DRIVER_SPEC,
413 };
414 if entry.phase_inverse {
415 val |= SNDRV_CHMAP_PHASE_INVERSE;
416 }
417 val
418 }
419}
420
421#[derive(Debug, Copy, Clone, PartialEq, Eq)]
423pub enum ChmapMode {
424 Fixed,
426 ArbitraryExchangeable,
429 PairedExchangeable,
432}
433
434impl Default for ChmapMode {
435 fn default() -> Self {
436 Self::Fixed
437 }
438}
439
440#[derive(Default, Debug, Clone, PartialEq, Eq)]
449pub struct Chmap {
450 pub mode: ChmapMode,
452 pub entries: Vec<ChmapEntry>,
454}
455
456impl<'a> TlvData<'a> for Chmap {
457 fn value_type(&self) -> u32 {
458 match self.mode {
459 ChmapMode::Fixed => SNDRV_CTL_TLVT_CHMAP_FIXED,
460 ChmapMode::ArbitraryExchangeable => SNDRV_CTL_TLVT_CHMAP_VAR,
461 ChmapMode::PairedExchangeable => SNDRV_CTL_TLVT_CHMAP_PAIRED,
462 }
463 }
464
465 fn value_length(&self) -> usize {
466 self.entries.len()
467 }
468
469 fn value(&self) -> Vec<u32> {
470 let mut raw = Vec::new();
471 self.entries
472 .iter()
473 .for_each(|&entry| raw.push(u32::from(entry)));
474 raw
475 }
476}
477
478const TYPES_FOR_CHMAP: &'static [u32] = &[
479 SNDRV_CTL_TLVT_CHMAP_FIXED,
480 SNDRV_CTL_TLVT_CHMAP_VAR,
481 SNDRV_CTL_TLVT_CHMAP_PAIRED,
482];
483
484impl std::convert::TryFrom<&[u32]> for Chmap {
485 type Error = TlvDecodeError;
486
487 fn try_from(raw: &[u32]) -> Result<Self, Self::Error> {
488 if raw.len() < 2 {
490 Err(Self::Error::new(TlvDecodeErrorCtx::Length(raw.len(), 2), 0))
491 } else {
492 let mode = match raw[0] {
494 SNDRV_CTL_TLVT_CHMAP_FIXED => Ok(ChmapMode::Fixed),
495 SNDRV_CTL_TLVT_CHMAP_VAR => Ok(ChmapMode::ArbitraryExchangeable),
496 SNDRV_CTL_TLVT_CHMAP_PAIRED => Ok(ChmapMode::PairedExchangeable),
497 _ => Err(Self::Error::new(
498 TlvDecodeErrorCtx::ValueType(raw[0], TYPES_FOR_CHMAP),
499 0,
500 )),
501 }?;
502
503 let value_length = (raw[1] / 4) as usize;
505 let value = &raw[2..];
506 if value.len() < value_length {
507 Err(Self::Error::new(
508 TlvDecodeErrorCtx::ValueLength(value_length, value.len()),
509 1,
510 ))
511 } else if mode == ChmapMode::PairedExchangeable && value.len() % 2 > 0 {
512 Err(Self::Error::new(
513 TlvDecodeErrorCtx::ValueLength(value_length, value.len()),
514 1,
515 ))
516 } else {
517 let entries = value.iter().map(|&val| ChmapEntry::from(val)).collect();
519 Ok(Self { mode, entries })
520 }
521 }
522 }
523}
524
525impl From<&Chmap> for Vec<u32> {
526 fn from(data: &Chmap) -> Self {
527 let mut raw = Vec::new();
528 raw.push(data.value_type());
529 raw.push(4 * data.value_length() as u32);
530 raw.append(&mut data.value());
531 raw
532 }
533}
534
535impl From<Chmap> for Vec<u32> {
536 fn from(data: Chmap) -> Self {
537 (&data).into()
538 }
539}
540
541#[cfg(test)]
542mod test {
543 use super::{Chmap, ChmapEntry, ChmapGenericPos, ChmapMode, ChmapPos};
544 use super::{DbInterval, DbScale};
545 use std::convert::TryFrom;
546
547 #[test]
548 fn test_dbitem() {
549 let raw = [1u32, 8, -10i32 as u32, 0x00000010];
550 let item = DbScale::try_from(raw.as_ref()).unwrap();
551 assert_eq!(item.min, -10);
552 assert_eq!(item.step, 16);
553 assert_eq!(item.mute_avail, false);
554 assert_eq!(&Vec::<u32>::from(item)[..], &raw[..]);
555 }
556
557 #[test]
558 fn test_dbitem_mute_avail() {
559 let raw = [1u32, 8, 10, 0x00010010];
560 let item = DbScale::try_from(raw.as_ref()).unwrap();
561 assert_eq!(item.min, 10);
562 assert_eq!(item.step, 16);
563 assert_eq!(item.mute_avail, true);
564 assert_eq!(&Vec::<u32>::from(item)[..], &raw[..]);
565 }
566
567 #[test]
568 fn test_dbinterval() {
569 let raw = [4u32, 8, -100i32 as u32, 100];
570 let item = DbInterval::try_from(&raw[..]).unwrap();
571 assert_eq!(item.min, -100);
572 assert_eq!(item.max, 100);
573 assert_eq!(item.linear, false);
574 assert_eq!(item.mute_avail, false);
575 assert_eq!(&Vec::<u32>::from(item)[..], &raw[..]);
576 }
577
578 #[test]
579 fn test_dbinterval_mute() {
580 let raw = [5u32, 8, -100i32 as u32, 100];
581 let item = DbInterval::try_from(&raw[..]).unwrap();
582 assert_eq!(item.min, -100);
583 assert_eq!(item.max, 100);
584 assert_eq!(item.linear, false);
585 assert_eq!(item.mute_avail, true);
586 assert_eq!(&Vec::<u32>::from(item)[..], &raw[..]);
587 }
588
589 #[test]
590 fn test_dbinterval_linear() {
591 let raw = [2u32, 8, -100i32 as u32, 100];
592 let item = DbInterval::try_from(&raw[..]).unwrap();
593 assert_eq!(item.min, -100);
594 assert_eq!(item.max, 100);
595 assert_eq!(item.linear, true);
596 assert_eq!(item.mute_avail, true);
597 assert_eq!(&Vec::<u32>::from(item)[..], &raw[..]);
598 }
599
600 #[test]
601 fn test_chmapgenericpos() {
602 (0..u16::MAX).for_each(|val| {
603 let generic_pos = ChmapGenericPos::from(val);
604 assert_eq!(u16::from(generic_pos), val);
605 });
606 }
607
608 #[test]
609 fn test_chmapentry() {
610 (0..37).for_each(|val| {
611 let raw = val as u32;
612 let entry = ChmapEntry::try_from(raw).unwrap();
613 assert_eq!(entry.phase_inverse, false);
614 assert_eq!(u32::from(entry), raw);
615
616 let raw = 0x00010000u32 | (val as u32);
617 let entry = ChmapEntry::try_from(raw).unwrap();
618 assert_eq!(entry.phase_inverse, true);
619 assert_eq!(u32::from(entry), raw);
620
621 let raw = 0x00020000u32 | (val as u32);
622 let entry = ChmapEntry::try_from(raw).unwrap();
623 assert_eq!(entry.phase_inverse, false);
624 assert_eq!(u32::from(entry), raw);
625 });
626 }
627
628 #[test]
629 fn test_chmap_fixed() {
630 let raw = [0x101u32, 8, 3, 4];
631 let map = Chmap::try_from(&raw[..]).unwrap();
632 assert_eq!(map.mode, ChmapMode::Fixed);
633 assert_eq!(
634 &map.entries[..],
635 &[
636 ChmapEntry {
637 pos: ChmapPos::Generic(ChmapGenericPos::FrontLeft),
638 phase_inverse: false
639 },
640 ChmapEntry {
641 pos: ChmapPos::Generic(ChmapGenericPos::FrontRight),
642 phase_inverse: false
643 },
644 ]
645 );
646 assert_eq!(&Vec::<u32>::from(map)[..], &raw[..]);
647 }
648
649 #[test]
650 fn test_chmap_arbitrary_exchangeable() {
651 let raw = [0x102u32, 12, 3, 4, 8];
652 let map = Chmap::try_from(&raw[..]).unwrap();
653 assert_eq!(map.mode, ChmapMode::ArbitraryExchangeable);
654 assert_eq!(
655 &map.entries[..],
656 &[
657 ChmapEntry {
658 pos: ChmapPos::Generic(ChmapGenericPos::FrontLeft),
659 phase_inverse: false
660 },
661 ChmapEntry {
662 pos: ChmapPos::Generic(ChmapGenericPos::FrontRight),
663 phase_inverse: false
664 },
665 ChmapEntry {
666 pos: ChmapPos::Generic(ChmapGenericPos::LowFrequencyEffect),
667 phase_inverse: false
668 },
669 ][..]
670 );
671 assert_eq!(&Vec::<u32>::from(map)[..], &raw[..]);
672 }
673
674 #[test]
675 fn test_chmap_paired_exchangeable() {
676 let raw = [0x103u32, 16, 3, 4, 5, 6];
677 let map = Chmap::try_from(&raw[..]).unwrap();
678 assert_eq!(map.mode, ChmapMode::PairedExchangeable);
679 assert_eq!(
680 &map.entries[..],
681 &[
682 ChmapEntry {
683 pos: ChmapPos::Generic(ChmapGenericPos::FrontLeft),
684 phase_inverse: false
685 },
686 ChmapEntry {
687 pos: ChmapPos::Generic(ChmapGenericPos::FrontRight),
688 phase_inverse: false
689 },
690 ChmapEntry {
691 pos: ChmapPos::Generic(ChmapGenericPos::RearLeft),
692 phase_inverse: false
693 },
694 ChmapEntry {
695 pos: ChmapPos::Generic(ChmapGenericPos::RearRight),
696 phase_inverse: false
697 },
698 ][..]
699 );
700 assert_eq!(&Vec::<u32>::from(map)[..], &raw[..]);
701 }
702}