1use std::fmt::Display;
2
3use num_derive::{FromPrimitive, ToPrimitive};
4use num_traits::FromPrimitive;
5use vpi_sys::{PLI_INT32, PLI_UINT32};
6
7use crate::{Handle, Property, Time};
8
9#[derive(Debug)]
11pub enum Value {
12 BinStr(String),
14 OctStr(String),
16 HexStr(String),
18 DecStr(String),
20 Scalar(ScalarValue),
22 Int(i32),
24 Real(f64),
26 String(String),
28 Vector(Vec<ScalarValue>),
30 Strength(StrengthValue),
32 Time(Time),
34 ObjType(i32),
42 Suppress,
44 ShortInt(i16),
46 LongInt(i64),
48 ShortReal(f32),
50 RawTwoState(Vec<bool>), RawFourState(Vec<ScalarValue>), }
55
56impl Display for Value {
57 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58 match self {
59 Value::BinStr(s) | Value::OctStr(s) | Value::HexStr(s) | Value::DecStr(s) => {
60 write!(f, "{s}")
61 }
62 Value::Scalar(scalar) => write!(f, "{scalar}"),
63 Value::Int(i) => write!(f, "{i}"),
64 Value::Real(r) => write!(f, "{r}"),
65 Value::String(s) => write!(f, "\"{s}\""),
66 Value::Vector(vec) => {
67 write!(
68 f,
69 "{}",
70 vec.iter().map(|s| format!("{s}")).collect::<String>()
71 )
72 }
73 Value::Strength(strength) => write!(f, "{strength}"),
74 Value::Time(time) => write!(f, "{time}"),
75 Value::ObjType(obj_type) => write!(f, "ObjType({obj_type})"), Value::Suppress => write!(f, "Suppress"),
77 Value::ShortInt(i) => write!(f, "{i}"),
78 Value::LongInt(i) => write!(f, "{i}"),
79 Value::ShortReal(r) => write!(f, "{r}"),
80 Value::RawTwoState(vec) => {
81 write!(
82 f,
83 "{}",
84 vec.iter()
85 .map(|b| if *b { '1' } else { '0' })
86 .collect::<String>()
87 )
88 }
89 Value::RawFourState(vec) => {
90 write!(
91 f,
92 "{}",
93 vec.iter().map(|s| format!("{s}")).collect::<String>()
94 )
95 }
96 }
97 }
98}
99
100#[repr(u32)]
101#[derive(FromPrimitive, ToPrimitive, Debug, Copy, Clone)]
102pub enum ValueType {
104 BinStr = vpi_sys::vpiBinStrVal,
106 OctStr = vpi_sys::vpiOctStrVal,
108 HexStr = vpi_sys::vpiHexStrVal,
110 DecStr = vpi_sys::vpiDecStrVal,
112 Scalar = vpi_sys::vpiScalarVal,
114 Int = vpi_sys::vpiIntVal,
116 Real = vpi_sys::vpiRealVal,
118 String = vpi_sys::vpiStringVal,
120 Vector = vpi_sys::vpiVectorVal,
122 Strength = vpi_sys::vpiStrengthVal,
124 Time = vpi_sys::vpiTimeVal,
126 ObjType = vpi_sys::vpiObjTypeVal,
133 Suppress = vpi_sys::vpiSuppressVal,
135 ShortInt = vpi_sys::vpiShortIntVal,
137 LongInt = vpi_sys::vpiLongIntVal,
139 ShortReal = vpi_sys::vpiShortRealVal,
141 RawTwoState = vpi_sys::vpiRawTwoStateVal,
143 RawFourState = vpi_sys::vpiRawFourStateVal,
145}
146
147impl std::fmt::Display for ValueType {
148 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
149 let type_name = match self {
150 ValueType::BinStr => "Binary String",
151 ValueType::OctStr => "Octal String",
152 ValueType::HexStr => "Hexadecimal String",
153 ValueType::DecStr => "Decimal String",
154 ValueType::Scalar => "Scalar",
155 ValueType::Int => "Integer",
156 ValueType::Real => "Real",
157 ValueType::String => "String",
158 ValueType::Vector => "Vector",
159 ValueType::Strength => "Strength",
160 ValueType::Time => "Time",
161 ValueType::ObjType => "Object Type",
162 ValueType::Suppress => "Suppress",
163 ValueType::ShortInt => "Short Integer",
164 ValueType::LongInt => "Long Integer",
165 ValueType::ShortReal => "Short Real",
166 ValueType::RawTwoState => "Raw Two-State Vector",
167 ValueType::RawFourState => "Raw Four-State Vector",
168 };
169 write!(f, "{type_name}")
170 }
171}
172
173#[repr(u32)]
174#[derive(FromPrimitive, ToPrimitive, Copy, Clone, Debug, PartialEq)]
175pub enum ScalarValue {
177 Zero = vpi_sys::vpi0,
179 One = vpi_sys::vpi1,
181 Z = vpi_sys::vpiZ,
183 X = vpi_sys::vpiX,
185 H = vpi_sys::vpiH,
187 L = vpi_sys::vpiL,
189 DontCare = vpi_sys::vpiDontCare,
191 NoChange = vpi_sys::vpiNoChange,
193}
194
195impl Display for ScalarValue {
196 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
197 write!(f, "{}", char::from(*self))
198 }
199}
200
201impl From<ScalarValue> for char {
202 fn from(value: ScalarValue) -> Self {
203 match value {
204 ScalarValue::Zero => '0',
205 ScalarValue::One => '1',
206 ScalarValue::X => 'X',
207 ScalarValue::Z => 'Z',
208 ScalarValue::H => 'H',
209 ScalarValue::L => 'L',
210 ScalarValue::DontCare => '-',
211 ScalarValue::NoChange => 'N',
212 }
213 }
214}
215
216#[derive(Debug)]
217pub struct StrengthValue {
219 logic: ScalarValue,
221 strength0: StrengthEncoding,
223 strength1: StrengthEncoding,
225}
226
227impl Display for StrengthValue {
228 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
229 write!(f, "{} ({}, {})", self.logic, self.strength0, self.strength1)
230 }
231}
232
233impl From<vpi_sys::t_vpi_strengthval> for StrengthValue {
234 fn from(strength: vpi_sys::t_vpi_strengthval) -> Self {
235 let logic = ScalarValue::from_u32(strength.logic as u32).unwrap_or(ScalarValue::DontCare);
236 let strength0 = StrengthEncoding::from_bits_truncate(strength.s0 as u32);
237 let strength1 = StrengthEncoding::from_bits_truncate(strength.s1 as u32);
238 Self {
239 logic,
240 strength0,
241 strength1,
242 }
243 }
244}
245
246bitflags::bitflags! {
247 #[derive(Debug)]
248 pub struct StrengthEncoding: u32 {
250 const SupplyDrive = vpi_sys::vpiSupplyDrive;
252 const StrongDrive = vpi_sys::vpiStrongDrive;
254 const PullDrive = vpi_sys::vpiPullDrive;
256 const LargeCharge = vpi_sys::vpiLargeCharge;
258 const WeakDrive = vpi_sys::vpiWeakDrive;
260 const MediumCharge = vpi_sys::vpiMediumCharge;
262 const SmallCharge = vpi_sys::vpiSmallCharge;
264 const HiZ = vpi_sys::vpiHiZ;
266 }
267}
268
269impl Display for StrengthEncoding {
270 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
271 let mut strengths = Vec::new();
272 if self.contains(StrengthEncoding::SupplyDrive) {
273 strengths.push("SupplyDrive");
274 }
275 if self.contains(StrengthEncoding::StrongDrive) {
276 strengths.push("StrongDrive");
277 }
278 if self.contains(StrengthEncoding::PullDrive) {
279 strengths.push("PullDrive");
280 }
281 if self.contains(StrengthEncoding::LargeCharge) {
282 strengths.push("LargeCharge");
283 }
284 if self.contains(StrengthEncoding::WeakDrive) {
285 strengths.push("WeakDrive");
286 }
287 if self.contains(StrengthEncoding::MediumCharge) {
288 strengths.push("MediumCharge");
289 }
290 if self.contains(StrengthEncoding::SmallCharge) {
291 strengths.push("SmallCharge");
292 }
293 if self.contains(StrengthEncoding::HiZ) {
294 strengths.push("HiZ");
295 }
296 write!(f, "{}", strengths.join(" | "))
297 }
298}
299
300bitflags::bitflags! {
301 pub struct PutValueFlags: u32 {
303 const ReturnEvent = vpi_sys::vpiReturnEvent;
305 const UserAllocFlag = vpi_sys::vpiUserAllocFlag;
307 const OneValue = vpi_sys::vpiOneValue;
309 const PropagateOff = vpi_sys::vpiPropagateOff;
311 }
312}
313
314#[must_use]
326pub fn vector_value_to_scalar_vector(
327 vec: &[vpi_sys::t_vpi_vecval],
328 size: usize,
329) -> Vec<ScalarValue> {
330 let mut result = Vec::with_capacity(size);
331
332 for bit_index in 0..size {
333 let word_index = bit_index / 32;
335 let bit_position = bit_index % 32;
337
338 if word_index >= vec.len() {
339 result.push(ScalarValue::Zero);
341 continue;
342 }
343
344 let vecval = &vec[word_index];
345
346 let a_bit = (vecval.aval >> bit_position) & 1;
348 let b_bit = (vecval.bval >> bit_position) & 1;
349
350 let encoded = (a_bit << 1) | b_bit;
353
354 let scalar = match encoded {
355 0 => ScalarValue::Zero,
356 1 => ScalarValue::Z,
357 2 => ScalarValue::One,
358 3 => ScalarValue::X,
359 _ => ScalarValue::DontCare, };
361
362 result.push(scalar);
363 }
364
365 result.reverse(); result
367}
368
369#[must_use]
374pub(crate) fn decode_vpi_value(
375 raw_value: vpi_sys::t_vpi_value,
376 obj: vpi_sys::vpiHandle,
377) -> Option<Value> {
378 match raw_value.format as u32 {
379 vpi_sys::vpiBinStrVal => {
380 let c_str = unsafe { std::ffi::CStr::from_ptr(raw_value.value.str_) };
381 Some(Value::BinStr(c_str.to_str().unwrap_or("").to_string()))
382 }
383 vpi_sys::vpiOctStrVal => {
384 let c_str = unsafe { std::ffi::CStr::from_ptr(raw_value.value.str_) };
385 Some(Value::OctStr(c_str.to_str().unwrap_or("").to_string()))
386 }
387 vpi_sys::vpiHexStrVal => {
388 let c_str = unsafe { std::ffi::CStr::from_ptr(raw_value.value.str_) };
389 Some(Value::HexStr(c_str.to_str().unwrap_or("").to_string()))
390 }
391 vpi_sys::vpiDecStrVal => {
392 let c_str = unsafe { std::ffi::CStr::from_ptr(raw_value.value.str_) };
393 Some(Value::DecStr(c_str.to_str().unwrap_or("").to_string()))
394 }
395 vpi_sys::vpiScalarVal => Some(Value::Scalar(
396 ScalarValue::from_u32(unsafe { raw_value.value.integer } as u32)
397 .unwrap_or(ScalarValue::DontCare),
398 )),
399 vpi_sys::vpiIntVal => Some(Value::Int(unsafe { raw_value.value.integer })),
400 vpi_sys::vpiRealVal => Some(Value::Real(unsafe { raw_value.value.real })),
401 vpi_sys::vpiStringVal => {
402 let c_str = unsafe { std::ffi::CStr::from_ptr(raw_value.value.str_) };
403 Some(Value::String(c_str.to_str().unwrap_or("").to_string()))
404 }
405 vpi_sys::vpiObjTypeVal => Some(Value::ObjType(unsafe { raw_value.value.integer })),
406 vpi_sys::vpiVectorVal => {
407 let vec_ptr = unsafe { raw_value.value.vector };
408 if vec_ptr.is_null() {
409 Some(Value::Vector(vec![]))
410 } else {
411 let size = if obj.is_null() {
412 0usize
413 } else {
414 unsafe { vpi_sys::vpi_get(vpi_sys::vpiSize as i32, obj) as usize }
415 };
416 let num_words = size.div_ceil(32);
417 let vec = unsafe { std::slice::from_raw_parts(vec_ptr, num_words) };
418 Some(Value::Vector(vector_value_to_scalar_vector(vec, size)))
419 }
420 }
421 vpi_sys::vpiStrengthVal => {
422 let strength: vpi_sys::t_vpi_strengthval = unsafe { *raw_value.value.strength };
423 Some(Value::Strength(StrengthValue::from(strength)))
424 }
425 vpi_sys::vpiTimeVal => {
426 let vpi_time: vpi_sys::t_vpi_time = unsafe { *raw_value.value.time };
427 Some(Value::Time(Time::from(vpi_time)))
428 }
429 vpi_sys::vpiShortIntVal => Some(Value::ShortInt(unsafe { raw_value.value.integer } as i16)),
430 _ => None,
431 }
432}
433
434#[cfg(feature = "bigint")]
440#[must_use]
441pub fn scalar_vector_to_biguint(bits: &[ScalarValue]) -> Option<num_bigint::BigUint> {
442 let mut result = num_bigint::BigUint::ZERO;
443 for bit in bits {
444 result <<= 1u32;
445 match bit {
446 ScalarValue::Zero => {}
447 ScalarValue::One => result |= num_bigint::BigUint::from(1u32),
448 _ => return None,
449 }
450 }
451 Some(result)
452}
453
454#[must_use]
460pub fn uint64_to_scalar_vector(value: u64, bits: usize) -> Vec<ScalarValue> {
461 (0..bits)
462 .rev()
463 .map(|i| {
464 if (value >> i) & 1 == 1 {
465 ScalarValue::One
466 } else {
467 ScalarValue::Zero
468 }
469 })
470 .collect()
471}
472
473#[must_use]
480pub fn scalar_vector_to_uint64(bits: &[ScalarValue]) -> Option<u64> {
481 if bits.len() > 64 {
482 return None;
483 }
484 let mut result: u64 = 0;
485 for bit in bits {
486 result <<= 1;
487 match bit {
488 ScalarValue::Zero => {}
489 ScalarValue::One => result |= 1,
490 _ => return None,
491 }
492 }
493 Some(result)
494}
495
496#[cfg(feature = "bigint")]
502#[must_use]
503pub fn biguint_to_scalar_vector(value: &num_bigint::BigUint, bits: usize) -> Vec<ScalarValue> {
504 (0..bits)
505 .rev()
506 .map(|i| {
507 if value.bit(i as u64) {
508 ScalarValue::One
509 } else {
510 ScalarValue::Zero
511 }
512 })
513 .collect()
514}
515
516#[must_use]
522pub fn int64_to_scalar_vector(value: i64, bits: usize) -> Vec<ScalarValue> {
523 uint64_to_scalar_vector(value as u64, bits)
524}
525
526#[must_use]
533pub fn scalar_vector_to_int64(bits: &[ScalarValue]) -> Option<i64> {
534 if bits.is_empty() || bits.len() > 64 {
535 return None;
536 }
537 let unsigned = scalar_vector_to_uint64(bits)?;
538 let shift = 64 - bits.len();
540 Some((unsigned << shift) as i64 >> shift)
541}
542
543#[cfg(feature = "bigint")]
550#[must_use]
551pub fn bigint_to_scalar_vector(value: &num_bigint::BigInt, bits: usize) -> Vec<ScalarValue> {
552 use num_bigint::Sign;
553 let unsigned: num_bigint::BigUint = if value.sign() == Sign::Minus {
555 let modulus = num_bigint::BigUint::from(1u32) << bits;
556 let mag = value.magnitude();
557 modulus - mag
558 } else {
559 value.magnitude().clone()
560 };
561 biguint_to_scalar_vector(&unsigned, bits)
562}
563
564#[cfg(feature = "bigint")]
571#[must_use]
572pub fn scalar_vector_to_bigint(bits: &[ScalarValue]) -> Option<num_bigint::BigInt> {
573 if bits.is_empty() {
574 return None;
575 }
576 let unsigned = scalar_vector_to_biguint(bits)?;
577 if bits[0] == ScalarValue::One {
579 let modulus = num_bigint::BigUint::from(1u32) << bits.len();
580 Some(num_bigint::BigInt::from(unsigned) - num_bigint::BigInt::from(modulus))
581 } else {
582 Some(num_bigint::BigInt::from(unsigned))
583 }
584}
585
586impl Handle {
587 #[must_use]
596 pub fn get_value(&self, format: ValueType) -> Option<Value> {
597 if self.is_null() {
598 return None;
599 }
600 let mut value = vpi_sys::t_vpi_value {
601 format: format as i32,
602 value: vpi_sys::t_vpi_value__bindgen_ty_1 { integer: 0 },
603 };
604 unsafe { vpi_sys::vpi_get_value(self.as_raw(), &raw mut value) };
605 decode_vpi_value(value, self.as_raw())
606 }
607
608 #[must_use]
630 pub fn get_value_array(&self, format: ValueType) -> Option<Vec<Value>> {
631 if self.is_null() {
632 return None;
633 }
634
635 let size =
636 unsafe { vpi_sys::vpi_get(vpi_sys::vpiSize as PLI_INT32, self.as_raw()) } as usize;
637
638 if size == 0 {
639 return Some(Vec::new());
640 }
641
642 match format {
643 ValueType::Int => {
644 let mut integers: Vec<i32> = vec![0; size];
645 let mut arrayvalue = vpi_sys::t_vpi_arrayvalue {
646 format: vpi_sys::vpiIntVal,
647 flags: 0,
648 value: vpi_sys::t_vpi_arrayvalue__bindgen_ty_1 {
649 integers: integers.as_mut_ptr(),
650 },
651 };
652 let mut index = 0;
653
654 unsafe {
655 vpi_sys::vpi_get_value_array(
656 self.as_raw(),
657 &raw mut arrayvalue,
658 &raw mut index,
659 size as PLI_UINT32,
660 );
661 }
662
663 Some(integers.into_iter().map(Value::Int).collect::<Vec<Value>>())
664 }
665 ValueType::Real => {
666 let mut reals: Vec<f64> = vec![0.0; size];
667 let mut arrayvalue = vpi_sys::t_vpi_arrayvalue {
668 format: vpi_sys::vpiRealVal,
669 flags: 0,
670 value: vpi_sys::t_vpi_arrayvalue__bindgen_ty_1 {
671 reals: reals.as_mut_ptr(),
672 },
673 };
674 let mut index = 0;
675
676 unsafe {
677 vpi_sys::vpi_get_value_array(
678 self.as_raw(),
679 &raw mut arrayvalue,
680 &raw mut index,
681 size as PLI_UINT32,
682 );
683 }
684
685 Some(reals.into_iter().map(Value::Real).collect::<Vec<Value>>())
686 }
687 ValueType::Time => {
688 let mut times: Vec<vpi_sys::t_vpi_time> = vec![
689 vpi_sys::t_vpi_time {
690 type_: 0,
691 high: 0,
692 low: 0,
693 real: 0.0,
694 };
695 size
696 ];
697 let mut arrayvalue = vpi_sys::t_vpi_arrayvalue {
698 format: vpi_sys::vpiTimeVal,
699 flags: 0,
700 value: vpi_sys::t_vpi_arrayvalue__bindgen_ty_1 {
701 times: times.as_mut_ptr(),
702 },
703 };
704 let mut index = 0;
705
706 unsafe {
707 vpi_sys::vpi_get_value_array(
708 self.as_raw(),
709 &raw mut arrayvalue,
710 &raw mut index,
711 size as PLI_UINT32,
712 );
713 }
714
715 Some(
716 times
717 .into_iter()
718 .map(|t| {
719 let vpi_time = vpi_sys::s_vpi_time {
720 type_: t.type_,
721 high: t.high,
722 low: t.low,
723 real: t.real,
724 };
725 Value::Time(Time::from(vpi_time))
726 })
727 .collect::<Vec<Value>>(),
728 )
729 }
730 ValueType::ShortInt => {
731 let mut shortints: Vec<i16> = vec![0; size];
732 let mut arrayvalue = vpi_sys::t_vpi_arrayvalue {
733 format: vpi_sys::vpiShortIntVal,
734 flags: 0,
735 value: vpi_sys::t_vpi_arrayvalue__bindgen_ty_1 {
736 shortints: shortints.as_mut_ptr(),
737 },
738 };
739 let mut index = 0;
740
741 unsafe {
742 vpi_sys::vpi_get_value_array(
743 self.as_raw(),
744 &raw mut arrayvalue,
745 &raw mut index,
746 size as PLI_UINT32,
747 );
748 }
749
750 Some(
751 shortints
752 .into_iter()
753 .map(Value::ShortInt)
754 .collect::<Vec<Value>>(),
755 )
756 }
757 ValueType::LongInt => {
758 let mut longints: Vec<i64> = vec![0; size];
759 let mut arrayvalue = vpi_sys::t_vpi_arrayvalue {
760 format: vpi_sys::vpiLongIntVal,
761 flags: 0,
762 value: vpi_sys::t_vpi_arrayvalue__bindgen_ty_1 {
763 longints: longints.as_mut_ptr(),
764 },
765 };
766 let mut index = 0;
767
768 unsafe {
769 vpi_sys::vpi_get_value_array(
770 self.as_raw(),
771 &raw mut arrayvalue,
772 &raw mut index,
773 size as PLI_UINT32,
774 );
775 }
776
777 Some(
778 longints
779 .into_iter()
780 .map(Value::LongInt)
781 .collect::<Vec<Value>>(),
782 )
783 }
784 ValueType::ShortReal => {
785 let mut shortreals: Vec<f32> = vec![0.0; size];
786 let mut arrayvalue = vpi_sys::t_vpi_arrayvalue {
787 format: vpi_sys::vpiShortRealVal,
788 flags: 0,
789 value: vpi_sys::t_vpi_arrayvalue__bindgen_ty_1 {
790 shortreals: shortreals.as_mut_ptr(),
791 },
792 };
793 let mut index = 0;
794
795 unsafe {
796 vpi_sys::vpi_get_value_array(
797 self.as_raw(),
798 &raw mut arrayvalue,
799 &raw mut index,
800 size as PLI_UINT32,
801 );
802 }
803
804 Some(
805 shortreals
806 .into_iter()
807 .map(Value::ShortReal)
808 .collect::<Vec<Value>>(),
809 )
810 }
811 ValueType::Vector => {
812 let mut values = Vec::with_capacity(size);
815 for _ in 0..size {
816 if let Some(val) = self.get_value(ValueType::Vector) {
817 values.push(val);
818 }
819 }
820 Some(values)
821 }
822 ValueType::Scalar => {
823 let mut rawvals: Vec<vpi_sys::PLI_BYTE8> = vec![0; size];
825 let mut arrayvalue = vpi_sys::t_vpi_arrayvalue {
826 format: vpi_sys::vpiScalarVal,
827 flags: 0,
828 value: vpi_sys::t_vpi_arrayvalue__bindgen_ty_1 {
829 rawvals: rawvals.as_mut_ptr(),
830 },
831 };
832 let mut index = 0;
833
834 unsafe {
835 vpi_sys::vpi_get_value_array(
836 self.as_raw(),
837 &raw mut arrayvalue,
838 &raw mut index,
839 size as PLI_UINT32,
840 );
841 }
842
843 Some(
844 rawvals
845 .into_iter()
846 .filter_map(|v| ScalarValue::from_u32(v as u32).map(Value::Scalar))
847 .collect::<Vec<Value>>(),
848 )
849 }
850 _ => {
851 Some(Vec::new())
853 }
854 }
855 }
856
857 #[must_use]
859 pub fn is_array(&self) -> bool {
860 if self.is_null() {
861 return false;
862 }
863 self.get_bool(Property::Array) == Some(true)
864 }
865}
866
867#[cfg(test)]
868mod tests {
869 use super::{
870 int64_to_scalar_vector, scalar_vector_to_int64, scalar_vector_to_uint64,
871 uint64_to_scalar_vector, vector_value_to_scalar_vector, ScalarValue, StrengthEncoding,
872 Value, ValueType,
873 };
874
875 fn scalar_vec_to_string(values: Vec<ScalarValue>) -> String {
876 values.into_iter().map(|value| value.to_string()).collect()
877 }
878
879 #[test]
880 fn vector_value_decodes_ab_encoding_and_reverses_bit_order() {
881 let vec = [vpi_sys::t_vpi_vecval {
882 aval: 0b1010,
883 bval: 0b1100,
884 }];
885 let decoded = vector_value_to_scalar_vector(&vec, 4);
886
887 assert_eq!(scalar_vec_to_string(decoded), "XZ10");
888 }
889
890 #[test]
891 fn vector_value_uses_zero_when_words_are_missing() {
892 let decoded = vector_value_to_scalar_vector(&[], 3);
893
894 assert_eq!(scalar_vec_to_string(decoded), "000");
895 }
896
897 #[test]
898 fn raw_two_state_display_renders_binary_string() {
899 let value = Value::RawTwoState(vec![true, false, true, true, false]);
900
901 assert_eq!(value.to_string(), "10110");
902 }
903
904 #[test]
905 fn raw_four_state_display_renders_scalar_symbols() {
906 let value = Value::RawFourState(vec![
907 ScalarValue::Zero,
908 ScalarValue::One,
909 ScalarValue::X,
910 ScalarValue::Z,
911 ScalarValue::DontCare,
912 ScalarValue::NoChange,
913 ]);
914
915 assert_eq!(value.to_string(), "01XZ-N");
916 }
917
918 #[test]
919 fn strength_encoding_display_joins_active_flags_in_order() {
920 let strength = StrengthEncoding::StrongDrive | StrengthEncoding::HiZ;
921
922 assert_eq!(strength.to_string(), "StrongDrive | HiZ");
923 }
924
925 #[test]
926 fn value_type_display_has_human_readable_labels() {
927 assert_eq!(ValueType::RawFourState.to_string(), "Raw Four-State Vector");
928 assert_eq!(ValueType::ShortInt.to_string(), "Short Integer");
929 }
930
931 #[test]
932 fn scalar_vector_to_uint64_converts_binary_bits() {
933 let bits = vec![
934 ScalarValue::One,
935 ScalarValue::Zero,
936 ScalarValue::One,
937 ScalarValue::One,
938 ];
939 assert_eq!(scalar_vector_to_uint64(&bits), Some(0b1011));
940 }
941
942 #[test]
943 fn scalar_vector_to_uint64_all_zeros() {
944 let bits = vec![ScalarValue::Zero; 8];
945 assert_eq!(scalar_vector_to_uint64(&bits), Some(0));
946 }
947
948 #[test]
949 fn scalar_vector_to_uint64_returns_none_for_x_bit() {
950 let bits = vec![ScalarValue::One, ScalarValue::X, ScalarValue::Zero];
951 assert_eq!(scalar_vector_to_uint64(&bits), None);
952 }
953
954 #[test]
955 fn scalar_vector_to_uint64_returns_none_for_z_bit() {
956 let bits = vec![ScalarValue::Zero, ScalarValue::Z];
957 assert_eq!(scalar_vector_to_uint64(&bits), None);
958 }
959
960 #[test]
961 fn scalar_vector_to_uint64_returns_none_for_over_64_bits() {
962 let bits = vec![ScalarValue::Zero; 65];
963 assert_eq!(scalar_vector_to_uint64(&bits), None);
964 }
965
966 #[test]
967 fn scalar_vector_to_uint64_accepts_exactly_64_bits() {
968 let mut bits = vec![ScalarValue::Zero; 63];
969 bits.push(ScalarValue::One);
970 assert_eq!(scalar_vector_to_uint64(&bits), Some(1));
971 }
972
973 #[test]
974 fn uint64_to_scalar_vector_converts_value() {
975 assert_eq!(
976 uint64_to_scalar_vector(0b1011, 4),
977 vec![
978 ScalarValue::One,
979 ScalarValue::Zero,
980 ScalarValue::One,
981 ScalarValue::One
982 ]
983 );
984 }
985
986 #[test]
987 fn uint64_to_scalar_vector_pads_with_zeros() {
988 assert_eq!(
989 uint64_to_scalar_vector(0b101, 6),
990 vec![
991 ScalarValue::Zero,
992 ScalarValue::Zero,
993 ScalarValue::Zero,
994 ScalarValue::One,
995 ScalarValue::Zero,
996 ScalarValue::One,
997 ]
998 );
999 }
1000
1001 #[test]
1002 fn uint64_to_scalar_vector_truncates_high_bits() {
1003 assert_eq!(
1005 uint64_to_scalar_vector(0b11011, 4),
1006 vec![
1007 ScalarValue::One,
1008 ScalarValue::Zero,
1009 ScalarValue::One,
1010 ScalarValue::One
1011 ]
1012 );
1013 }
1014
1015 #[test]
1016 fn uint64_to_scalar_vector_zero_bits_returns_empty() {
1017 assert_eq!(uint64_to_scalar_vector(42, 0), vec![]);
1018 }
1019
1020 #[test]
1021 fn int64_to_scalar_vector_positive_value() {
1022 assert_eq!(
1023 int64_to_scalar_vector(5, 4),
1024 vec![
1025 ScalarValue::Zero,
1026 ScalarValue::One,
1027 ScalarValue::Zero,
1028 ScalarValue::One
1029 ]
1030 );
1031 }
1032
1033 #[test]
1034 fn int64_to_scalar_vector_negative_value() {
1035 assert_eq!(
1037 int64_to_scalar_vector(-1, 4),
1038 vec![
1039 ScalarValue::One,
1040 ScalarValue::One,
1041 ScalarValue::One,
1042 ScalarValue::One
1043 ]
1044 );
1045 }
1046
1047 #[test]
1048 fn int64_to_scalar_vector_min_negative() {
1049 assert_eq!(
1051 int64_to_scalar_vector(-8, 4),
1052 vec![
1053 ScalarValue::One,
1054 ScalarValue::Zero,
1055 ScalarValue::Zero,
1056 ScalarValue::Zero
1057 ]
1058 );
1059 }
1060
1061 #[test]
1062 fn scalar_vector_to_int64_positive() {
1063 let bits = vec![
1064 ScalarValue::Zero,
1065 ScalarValue::One,
1066 ScalarValue::Zero,
1067 ScalarValue::One,
1068 ];
1069 assert_eq!(scalar_vector_to_int64(&bits), Some(5));
1070 }
1071
1072 #[test]
1073 fn scalar_vector_to_int64_negative() {
1074 let bits = vec![
1076 ScalarValue::One,
1077 ScalarValue::One,
1078 ScalarValue::One,
1079 ScalarValue::One,
1080 ];
1081 assert_eq!(scalar_vector_to_int64(&bits), Some(-1));
1082 }
1083
1084 #[test]
1085 fn scalar_vector_to_int64_min_negative() {
1086 let bits = vec![
1088 ScalarValue::One,
1089 ScalarValue::Zero,
1090 ScalarValue::Zero,
1091 ScalarValue::Zero,
1092 ];
1093 assert_eq!(scalar_vector_to_int64(&bits), Some(-8));
1094 }
1095
1096 #[test]
1097 fn scalar_vector_to_int64_returns_none_for_empty() {
1098 assert_eq!(scalar_vector_to_int64(&[]), None);
1099 }
1100
1101 #[test]
1102 fn scalar_vector_to_int64_returns_none_for_over_64_bits() {
1103 let bits = vec![ScalarValue::Zero; 65];
1104 assert_eq!(scalar_vector_to_int64(&bits), None);
1105 }
1106
1107 #[test]
1108 fn scalar_vector_to_int64_returns_none_for_x_bit() {
1109 let bits = vec![ScalarValue::One, ScalarValue::X];
1110 assert_eq!(scalar_vector_to_int64(&bits), None);
1111 }
1112
1113 #[cfg(feature = "bigint")]
1114 mod bigint_tests {
1115 use num_bigint::{BigInt, BigUint};
1116
1117 use super::super::{
1118 bigint_to_scalar_vector, biguint_to_scalar_vector, scalar_vector_to_bigint,
1119 scalar_vector_to_biguint, ScalarValue,
1120 };
1121
1122 #[test]
1123 fn scalar_vector_to_biguint_converts_binary_bits() {
1124 let bits = vec![
1125 ScalarValue::One,
1126 ScalarValue::Zero,
1127 ScalarValue::One,
1128 ScalarValue::One,
1129 ];
1130 assert_eq!(
1131 scalar_vector_to_biguint(&bits),
1132 Some(BigUint::from(0b1011u32))
1133 );
1134 }
1135
1136 #[test]
1137 fn scalar_vector_to_biguint_all_zeros() {
1138 let bits = vec![ScalarValue::Zero; 8];
1139 assert_eq!(scalar_vector_to_biguint(&bits), Some(BigUint::ZERO));
1140 }
1141
1142 #[test]
1143 fn scalar_vector_to_biguint_empty_slice() {
1144 assert_eq!(scalar_vector_to_biguint(&[]), Some(BigUint::ZERO));
1145 }
1146
1147 #[test]
1148 fn scalar_vector_to_biguint_returns_none_for_x_bit() {
1149 let bits = vec![ScalarValue::One, ScalarValue::X, ScalarValue::Zero];
1150 assert_eq!(scalar_vector_to_biguint(&bits), None);
1151 }
1152
1153 #[test]
1154 fn scalar_vector_to_biguint_returns_none_for_z_bit() {
1155 let bits = vec![ScalarValue::Zero, ScalarValue::Z];
1156 assert_eq!(scalar_vector_to_biguint(&bits), None);
1157 }
1158
1159 #[test]
1160 fn scalar_vector_to_biguint_exceeds_64_bits() {
1161 let mut bits = vec![ScalarValue::Zero; 64];
1162 bits.push(ScalarValue::One);
1163 assert_eq!(scalar_vector_to_biguint(&bits), Some(BigUint::from(1u32)));
1165 }
1166
1167 #[test]
1168 fn biguint_to_scalar_vector_converts_value() {
1169 assert_eq!(
1170 biguint_to_scalar_vector(&BigUint::from(0b1011u32), 4),
1171 vec![
1172 ScalarValue::One,
1173 ScalarValue::Zero,
1174 ScalarValue::One,
1175 ScalarValue::One
1176 ]
1177 );
1178 }
1179
1180 #[test]
1181 fn biguint_to_scalar_vector_pads_with_zeros() {
1182 assert_eq!(
1183 biguint_to_scalar_vector(&BigUint::from(0b101u32), 6),
1184 vec![
1185 ScalarValue::Zero,
1186 ScalarValue::Zero,
1187 ScalarValue::Zero,
1188 ScalarValue::One,
1189 ScalarValue::Zero,
1190 ScalarValue::One,
1191 ]
1192 );
1193 }
1194
1195 #[test]
1196 fn biguint_to_scalar_vector_truncates_high_bits() {
1197 assert_eq!(
1199 biguint_to_scalar_vector(&BigUint::from(0b11011u32), 4),
1200 vec![
1201 ScalarValue::One,
1202 ScalarValue::Zero,
1203 ScalarValue::One,
1204 ScalarValue::One
1205 ]
1206 );
1207 }
1208
1209 #[test]
1210 fn biguint_to_scalar_vector_zero_bits_returns_empty() {
1211 assert_eq!(biguint_to_scalar_vector(&BigUint::from(42u32), 0), vec![]);
1212 }
1213
1214 #[test]
1215 fn biguint_to_scalar_vector_exceeds_64_bits() {
1216 let value = BigUint::from(1u32) << 64u32;
1217 let mut expected = vec![ScalarValue::One];
1218 expected.extend(vec![ScalarValue::Zero; 64]);
1219 assert_eq!(biguint_to_scalar_vector(&value, 65), expected);
1220 }
1221
1222 #[test]
1223 fn bigint_to_scalar_vector_positive_value() {
1224 assert_eq!(
1225 bigint_to_scalar_vector(&BigInt::from(5), 4),
1226 vec![
1227 ScalarValue::Zero,
1228 ScalarValue::One,
1229 ScalarValue::Zero,
1230 ScalarValue::One
1231 ]
1232 );
1233 }
1234
1235 #[test]
1236 fn bigint_to_scalar_vector_negative_one() {
1237 assert_eq!(
1239 bigint_to_scalar_vector(&BigInt::from(-1), 4),
1240 vec![
1241 ScalarValue::One,
1242 ScalarValue::One,
1243 ScalarValue::One,
1244 ScalarValue::One
1245 ]
1246 );
1247 }
1248
1249 #[test]
1250 fn bigint_to_scalar_vector_large_negative() {
1251 let expected = vec![ScalarValue::One; 65];
1253 assert_eq!(bigint_to_scalar_vector(&BigInt::from(-1), 65), expected);
1254 }
1255
1256 #[test]
1257 fn scalar_vector_to_bigint_positive() {
1258 let bits = vec![
1259 ScalarValue::Zero,
1260 ScalarValue::One,
1261 ScalarValue::Zero,
1262 ScalarValue::One,
1263 ];
1264 assert_eq!(scalar_vector_to_bigint(&bits), Some(BigInt::from(5)));
1265 }
1266
1267 #[test]
1268 fn scalar_vector_to_bigint_negative_one() {
1269 let bits = vec![
1271 ScalarValue::One,
1272 ScalarValue::One,
1273 ScalarValue::One,
1274 ScalarValue::One,
1275 ];
1276 assert_eq!(scalar_vector_to_bigint(&bits), Some(BigInt::from(-1)));
1277 }
1278
1279 #[test]
1280 fn scalar_vector_to_bigint_large_negative() {
1281 let bits = vec![ScalarValue::One; 65];
1283 assert_eq!(scalar_vector_to_bigint(&bits), Some(BigInt::from(-1)));
1284 }
1285
1286 #[test]
1287 fn scalar_vector_to_bigint_returns_none_for_empty() {
1288 assert_eq!(scalar_vector_to_bigint(&[]), None);
1289 }
1290
1291 #[test]
1292 fn scalar_vector_to_bigint_returns_none_for_x_bit() {
1293 let bits = vec![ScalarValue::One, ScalarValue::X];
1294 assert_eq!(scalar_vector_to_bigint(&bits), None);
1295 }
1296 }
1297}