1use fop_types::{Color, EvalContext, Expression, Gradient, Length, Percentage};
4use std::borrow::Cow;
5
6#[derive(Debug, Clone, Copy, PartialEq)]
10pub enum RelativeFontSize {
11 Larger,
13 Smaller,
15 XxSmall,
17 XSmall,
19 Small,
21 Medium,
23 Large,
25 XLarge,
27 XxLarge,
29}
30
31impl RelativeFontSize {
32 pub fn parse(s: &str) -> Option<Self> {
34 match s {
35 "larger" => Some(RelativeFontSize::Larger),
36 "smaller" => Some(RelativeFontSize::Smaller),
37 "xx-small" => Some(RelativeFontSize::XxSmall),
38 "x-small" => Some(RelativeFontSize::XSmall),
39 "small" => Some(RelativeFontSize::Small),
40 "medium" => Some(RelativeFontSize::Medium),
41 "large" => Some(RelativeFontSize::Large),
42 "x-large" => Some(RelativeFontSize::XLarge),
43 "xx-large" => Some(RelativeFontSize::XxLarge),
44 _ => None,
45 }
46 }
47
48 pub fn resolve(&self, parent_size: Length) -> Length {
53 match self {
54 RelativeFontSize::Larger => {
55 Length::from_millipoints((parent_size.millipoints() as f64 * 1.2) as i32)
57 }
58 RelativeFontSize::Smaller => {
59 Length::from_millipoints((parent_size.millipoints() as f64 / 1.2) as i32)
61 }
62 RelativeFontSize::XxSmall => Length::from_pt(9.0),
64 RelativeFontSize::XSmall => Length::from_pt(10.0),
65 RelativeFontSize::Small => Length::from_pt(13.0),
66 RelativeFontSize::Medium => Length::from_pt(16.0),
67 RelativeFontSize::Large => Length::from_pt(18.0),
68 RelativeFontSize::XLarge => Length::from_pt(24.0),
69 RelativeFontSize::XxLarge => Length::from_pt(32.0),
70 }
71 }
72
73 pub fn is_relative(&self) -> bool {
75 matches!(self, RelativeFontSize::Larger | RelativeFontSize::Smaller)
76 }
77
78 pub fn is_absolute_keyword(&self) -> bool {
80 !self.is_relative()
81 }
82}
83
84#[derive(Debug, Clone, PartialEq)]
86pub enum PropertyValue {
87 Length(Length),
89
90 Color(Color),
92
93 Gradient(Gradient),
95
96 Enum(u16),
98
99 String(Cow<'static, str>),
101
102 Percentage(Percentage),
104
105 Integer(i32),
107
108 Number(f64),
110
111 Boolean(bool),
113
114 List(Vec<PropertyValue>),
116
117 Pair(Box<PropertyValue>, Box<PropertyValue>),
119
120 RelativeFontSize(RelativeFontSize),
122
123 Expression(Expression),
125
126 Auto,
128
129 None,
131
132 Inherit,
134}
135
136impl PropertyValue {
137 #[inline]
139 pub fn is_auto(&self) -> bool {
140 matches!(self, PropertyValue::Auto)
141 }
142
143 #[inline]
145 pub fn is_none(&self) -> bool {
146 matches!(self, PropertyValue::None)
147 }
148
149 #[inline]
151 pub fn is_inherit(&self) -> bool {
152 matches!(self, PropertyValue::Inherit)
153 }
154
155 pub fn as_length(&self) -> Option<Length> {
157 match self {
158 PropertyValue::Length(len) => Some(*len),
159 _ => None,
160 }
161 }
162
163 pub fn as_relative_font_size(&self) -> Option<RelativeFontSize> {
165 match self {
166 PropertyValue::RelativeFontSize(rfs) => Some(*rfs),
167 _ => None,
168 }
169 }
170
171 pub fn resolve_font_size(&self, parent_size: Length) -> Option<Length> {
176 match self {
177 PropertyValue::Length(len) => Some(*len),
178 PropertyValue::RelativeFontSize(rfs) => Some(rfs.resolve(parent_size)),
179 _ => None,
180 }
181 }
182
183 pub fn as_color(&self) -> Option<Color> {
185 match self {
186 PropertyValue::Color(color) => Some(*color),
187 _ => None,
188 }
189 }
190
191 pub fn as_gradient(&self) -> Option<&Gradient> {
193 match self {
194 PropertyValue::Gradient(gradient) => Some(gradient),
195 _ => None,
196 }
197 }
198
199 pub fn as_enum(&self) -> Option<u16> {
201 match self {
202 PropertyValue::Enum(e) => Some(*e),
203 _ => None,
204 }
205 }
206
207 pub fn as_string(&self) -> Option<&str> {
209 match self {
210 PropertyValue::String(s) => Some(s.as_ref()),
211 _ => None,
212 }
213 }
214
215 pub fn as_integer(&self) -> Option<i32> {
217 match self {
218 PropertyValue::Integer(i) => Some(*i),
219 _ => None,
220 }
221 }
222
223 pub fn as_number(&self) -> Option<f64> {
225 match self {
226 PropertyValue::Number(n) => Some(*n),
227 _ => None,
228 }
229 }
230
231 pub fn as_boolean(&self) -> Option<bool> {
233 match self {
234 PropertyValue::Boolean(b) => Some(*b),
235 _ => None,
236 }
237 }
238
239 pub fn as_percentage(&self) -> Option<Percentage> {
241 match self {
242 PropertyValue::Percentage(p) => Some(*p),
243 _ => None,
244 }
245 }
246
247 pub fn resolve_length(&self, base: Length) -> Option<Length> {
249 match self {
250 PropertyValue::Length(len) => Some(*len),
251 PropertyValue::Percentage(pct) => Some(pct.of(base)),
252 _ => None,
253 }
254 }
255
256 pub fn as_expression(&self) -> Option<&Expression> {
258 match self {
259 PropertyValue::Expression(expr) => Some(expr),
260 _ => None,
261 }
262 }
263
264 pub fn resolve_with_context(&self, context: &EvalContext) -> Option<Length> {
266 match self {
267 PropertyValue::Length(len) => Some(*len),
268 PropertyValue::Percentage(pct) => context.base_width.map(|base| pct.of(base)),
269 PropertyValue::Expression(expr) => expr.evaluate(context).ok(),
270 _ => None,
271 }
272 }
273}
274
275#[cfg(test)]
276mod tests {
277 use super::*;
278
279 #[test]
280 fn test_length_value() {
281 let val = PropertyValue::Length(Length::from_pt(12.0));
282 assert!(val.as_length().is_some());
283 assert_eq!(
284 val.as_length().expect("test: should succeed"),
285 Length::from_pt(12.0)
286 );
287 }
288
289 #[test]
290 fn test_color_value() {
291 let val = PropertyValue::Color(Color::RED);
292 assert!(val.as_color().is_some());
293 assert_eq!(val.as_color().expect("test: should succeed"), Color::RED);
294 }
295
296 #[test]
297 fn test_enum_value() {
298 let val = PropertyValue::Enum(42);
299 assert_eq!(val.as_enum(), Some(42));
300 }
301
302 #[test]
303 fn test_string_value() {
304 let val = PropertyValue::String(Cow::Borrowed("test"));
305 assert_eq!(val.as_string(), Some("test"));
306 }
307
308 #[test]
309 fn test_special_values() {
310 assert!(PropertyValue::Auto.is_auto());
311 assert!(PropertyValue::None.is_none());
312 assert!(PropertyValue::Inherit.is_inherit());
313 }
314
315 #[test]
316 fn test_pair_value() {
317 let val = PropertyValue::Pair(
318 Box::new(PropertyValue::Length(Length::from_pt(10.0))),
319 Box::new(PropertyValue::Length(Length::from_pt(20.0))),
320 );
321
322 match val {
323 PropertyValue::Pair(first, second) => {
324 assert_eq!(first.as_length(), Some(Length::from_pt(10.0)));
325 assert_eq!(second.as_length(), Some(Length::from_pt(20.0)));
326 }
327 _ => panic!("Expected Pair"),
328 }
329 }
330
331 #[test]
332 fn test_relative_font_size_parsing() {
333 assert_eq!(
334 RelativeFontSize::parse("larger"),
335 Some(RelativeFontSize::Larger)
336 );
337 assert_eq!(
338 RelativeFontSize::parse("smaller"),
339 Some(RelativeFontSize::Smaller)
340 );
341 assert_eq!(
342 RelativeFontSize::parse("xx-small"),
343 Some(RelativeFontSize::XxSmall)
344 );
345 assert_eq!(
346 RelativeFontSize::parse("x-small"),
347 Some(RelativeFontSize::XSmall)
348 );
349 assert_eq!(
350 RelativeFontSize::parse("small"),
351 Some(RelativeFontSize::Small)
352 );
353 assert_eq!(
354 RelativeFontSize::parse("medium"),
355 Some(RelativeFontSize::Medium)
356 );
357 assert_eq!(
358 RelativeFontSize::parse("large"),
359 Some(RelativeFontSize::Large)
360 );
361 assert_eq!(
362 RelativeFontSize::parse("x-large"),
363 Some(RelativeFontSize::XLarge)
364 );
365 assert_eq!(
366 RelativeFontSize::parse("xx-large"),
367 Some(RelativeFontSize::XxLarge)
368 );
369 assert_eq!(RelativeFontSize::parse("invalid"), None);
370 }
371
372 #[test]
373 fn test_relative_font_size_larger() {
374 let parent = Length::from_pt(12.0);
375 let larger = RelativeFontSize::Larger;
376 let result = larger.resolve(parent);
377 assert_eq!(result, Length::from_pt(14.4));
379 }
380
381 #[test]
382 fn test_relative_font_size_smaller() {
383 let parent = Length::from_pt(12.0);
384 let smaller = RelativeFontSize::Smaller;
385 let result = smaller.resolve(parent);
386 assert_eq!(result, Length::from_pt(10.0));
388 }
389
390 #[test]
391 fn test_relative_font_size_absolute_keywords() {
392 assert_eq!(
393 RelativeFontSize::XxSmall.resolve(Length::from_pt(100.0)),
394 Length::from_pt(9.0)
395 );
396 assert_eq!(
397 RelativeFontSize::XSmall.resolve(Length::from_pt(100.0)),
398 Length::from_pt(10.0)
399 );
400 assert_eq!(
401 RelativeFontSize::Small.resolve(Length::from_pt(100.0)),
402 Length::from_pt(13.0)
403 );
404 assert_eq!(
405 RelativeFontSize::Medium.resolve(Length::from_pt(100.0)),
406 Length::from_pt(16.0)
407 );
408 assert_eq!(
409 RelativeFontSize::Large.resolve(Length::from_pt(100.0)),
410 Length::from_pt(18.0)
411 );
412 assert_eq!(
413 RelativeFontSize::XLarge.resolve(Length::from_pt(100.0)),
414 Length::from_pt(24.0)
415 );
416 assert_eq!(
417 RelativeFontSize::XxLarge.resolve(Length::from_pt(100.0)),
418 Length::from_pt(32.0)
419 );
420 }
421
422 #[test]
423 fn test_relative_font_size_checks() {
424 assert!(RelativeFontSize::Larger.is_relative());
425 assert!(RelativeFontSize::Smaller.is_relative());
426 assert!(!RelativeFontSize::Medium.is_relative());
427 assert!(RelativeFontSize::Medium.is_absolute_keyword());
428 assert!(RelativeFontSize::Large.is_absolute_keyword());
429 assert!(!RelativeFontSize::Larger.is_absolute_keyword());
430 }
431
432 #[test]
433 fn test_property_value_relative_font_size() {
434 let val = PropertyValue::RelativeFontSize(RelativeFontSize::Larger);
435 assert!(val.as_relative_font_size().is_some());
436 assert_eq!(val.as_relative_font_size(), Some(RelativeFontSize::Larger));
437 }
438
439 #[test]
440 fn test_resolve_font_size_with_length() {
441 let val = PropertyValue::Length(Length::from_pt(14.0));
442 let parent = Length::from_pt(12.0);
443 assert_eq!(val.resolve_font_size(parent), Some(Length::from_pt(14.0)));
444 }
445
446 #[test]
447 fn test_resolve_font_size_with_larger() {
448 let val = PropertyValue::RelativeFontSize(RelativeFontSize::Larger);
449 let parent = Length::from_pt(12.0);
450 assert_eq!(val.resolve_font_size(parent), Some(Length::from_pt(14.4)));
452 }
453
454 #[test]
455 fn test_resolve_font_size_with_smaller() {
456 let val = PropertyValue::RelativeFontSize(RelativeFontSize::Smaller);
457 let parent = Length::from_pt(12.0);
458 assert_eq!(val.resolve_font_size(parent), Some(Length::from_pt(10.0)));
460 }
461
462 #[test]
463 fn test_resolve_font_size_with_medium_keyword() {
464 let val = PropertyValue::RelativeFontSize(RelativeFontSize::Medium);
465 let parent = Length::from_pt(12.0);
466 assert_eq!(val.resolve_font_size(parent), Some(Length::from_pt(16.0)));
468 }
469
470 #[test]
471 fn test_resolve_font_size_with_invalid_type() {
472 let val = PropertyValue::String(Cow::Borrowed("test"));
473 let parent = Length::from_pt(12.0);
474 assert_eq!(val.resolve_font_size(parent), None);
475 }
476
477 #[test]
478 fn test_expression_value() {
479 let expr = Expression::parse("calc(100% - 20pt)").expect("test: should succeed");
480 let val = PropertyValue::Expression(expr);
481 assert!(val.as_expression().is_some());
482 }
483
484 #[test]
485 fn test_resolve_with_context_expression() {
486 let expr = Expression::parse("calc(100% - 20pt)").expect("test: should succeed");
487 let val = PropertyValue::Expression(expr);
488 let ctx = EvalContext::with_width(Length::from_pt(200.0), Length::from_pt(12.0));
489 let result = val
490 .resolve_with_context(&ctx)
491 .expect("test: should succeed");
492 assert_eq!(result, Length::from_pt(180.0));
493 }
494
495 #[test]
496 fn test_resolve_with_context_length() {
497 let val = PropertyValue::Length(Length::from_pt(50.0));
498 let ctx = EvalContext::with_width(Length::from_pt(200.0), Length::from_pt(12.0));
499 let result = val
500 .resolve_with_context(&ctx)
501 .expect("test: should succeed");
502 assert_eq!(result, Length::from_pt(50.0));
503 }
504
505 #[test]
506 fn test_resolve_with_context_percentage() {
507 let val = PropertyValue::Percentage(Percentage::from_percent(50.0));
508 let ctx = EvalContext::with_width(Length::from_pt(200.0), Length::from_pt(12.0));
509 let result = val
510 .resolve_with_context(&ctx)
511 .expect("test: should succeed");
512 assert_eq!(result, Length::from_pt(100.0));
513 }
514}
515
516#[cfg(test)]
518mod additional_tests {
519 use super::*;
520 use fop_types::{Color, Length, Percentage};
521
522 #[test]
525 fn test_is_auto() {
526 assert!(PropertyValue::Auto.is_auto());
527 assert!(!PropertyValue::None.is_auto());
528 assert!(!PropertyValue::Inherit.is_auto());
529 assert!(!PropertyValue::Length(Length::from_pt(0.0)).is_auto());
530 }
531
532 #[test]
533 fn test_is_none() {
534 assert!(PropertyValue::None.is_none());
535 assert!(!PropertyValue::Auto.is_none());
536 assert!(!PropertyValue::Inherit.is_none());
537 assert!(!PropertyValue::Integer(0).is_none());
538 }
539
540 #[test]
541 fn test_is_inherit() {
542 assert!(PropertyValue::Inherit.is_inherit());
543 assert!(!PropertyValue::Auto.is_inherit());
544 assert!(!PropertyValue::None.is_inherit());
545 assert!(!PropertyValue::Boolean(false).is_inherit());
546 }
547
548 #[test]
549 fn test_as_length_returns_none_for_auto() {
550 assert!(PropertyValue::Auto.as_length().is_none());
551 }
552
553 #[test]
554 fn test_as_length_returns_none_for_none() {
555 assert!(PropertyValue::None.as_length().is_none());
556 }
557
558 #[test]
559 fn test_as_length_returns_none_for_integer() {
560 assert!(PropertyValue::Integer(42).as_length().is_none());
561 }
562
563 #[test]
564 fn test_as_color_returns_none_for_length() {
565 assert!(PropertyValue::Length(Length::from_pt(10.0))
566 .as_color()
567 .is_none());
568 }
569
570 #[test]
571 fn test_as_enum_returns_none_for_string() {
572 assert!(PropertyValue::String(std::borrow::Cow::Borrowed("foo"))
573 .as_enum()
574 .is_none());
575 }
576
577 #[test]
578 #[allow(clippy::approx_constant)]
579 fn test_as_integer_returns_none_for_number() {
580 assert!(PropertyValue::Number(3.14).as_integer().is_none());
581 }
582
583 #[test]
584 fn test_as_number_returns_none_for_integer() {
585 assert!(PropertyValue::Integer(42).as_number().is_none());
586 }
587
588 #[test]
589 fn test_as_boolean_returns_none_for_enum() {
590 assert!(PropertyValue::Enum(1).as_boolean().is_none());
591 }
592
593 #[test]
594 fn test_as_percentage_returns_none_for_length() {
595 assert!(PropertyValue::Length(Length::from_pt(50.0))
596 .as_percentage()
597 .is_none());
598 }
599
600 #[test]
601 fn test_as_string_returns_none_for_color() {
602 assert!(PropertyValue::Color(Color::RED).as_string().is_none());
603 }
604
605 #[test]
608 fn test_integer_value_positive() {
609 let v = PropertyValue::Integer(42);
610 assert_eq!(v.as_integer(), Some(42));
611 }
612
613 #[test]
614 fn test_integer_value_negative() {
615 let v = PropertyValue::Integer(-7);
616 assert_eq!(v.as_integer(), Some(-7));
617 }
618
619 #[test]
620 fn test_integer_value_zero() {
621 let v = PropertyValue::Integer(0);
622 assert_eq!(v.as_integer(), Some(0));
623 }
624
625 #[test]
626 #[allow(clippy::approx_constant)]
627 fn test_number_value_positive() {
628 let v = PropertyValue::Number(3.14);
629 assert_eq!(v.as_number(), Some(3.14));
630 }
631
632 #[test]
633 fn test_number_value_zero() {
634 let v = PropertyValue::Number(0.0);
635 assert_eq!(v.as_number(), Some(0.0));
636 }
637
638 #[test]
639 fn test_boolean_true() {
640 let v = PropertyValue::Boolean(true);
641 assert_eq!(v.as_boolean(), Some(true));
642 }
643
644 #[test]
645 fn test_boolean_false() {
646 let v = PropertyValue::Boolean(false);
647 assert_eq!(v.as_boolean(), Some(false));
648 }
649
650 #[test]
651 fn test_percentage_value() {
652 let v = PropertyValue::Percentage(Percentage::from_percent(75.0));
653 assert_eq!(v.as_percentage(), Some(Percentage::from_percent(75.0)));
654 }
655
656 #[test]
657 fn test_pair_value_access() {
658 let v = PropertyValue::Pair(
659 Box::new(PropertyValue::Length(Length::from_pt(10.0))),
660 Box::new(PropertyValue::Length(Length::from_pt(20.0))),
661 );
662 match v {
663 PropertyValue::Pair(a, b) => {
664 assert_eq!(a.as_length(), Some(Length::from_pt(10.0)));
665 assert_eq!(b.as_length(), Some(Length::from_pt(20.0)));
666 }
667 _ => panic!("Expected Pair"),
668 }
669 }
670
671 #[test]
672 fn test_list_value_empty() {
673 let v = PropertyValue::List(vec![]);
674 match v {
675 PropertyValue::List(items) => assert!(items.is_empty()),
676 _ => panic!("Expected List"),
677 }
678 }
679
680 #[test]
681 fn test_list_value_with_items() {
682 let v = PropertyValue::List(vec![
683 PropertyValue::Integer(1),
684 PropertyValue::Integer(2),
685 PropertyValue::Integer(3),
686 ]);
687 match v {
688 PropertyValue::List(items) => {
689 assert_eq!(items.len(), 3);
690 assert_eq!(items[0].as_integer(), Some(1));
691 assert_eq!(items[2].as_integer(), Some(3));
692 }
693 _ => panic!("Expected List"),
694 }
695 }
696
697 #[test]
700 fn test_resolve_length_with_length() {
701 let v = PropertyValue::Length(Length::from_pt(30.0));
702 let result = v.resolve_length(Length::from_pt(100.0));
703 assert_eq!(result, Some(Length::from_pt(30.0)));
704 }
705
706 #[test]
707 fn test_resolve_length_with_percentage() {
708 let v = PropertyValue::Percentage(Percentage::from_percent(25.0));
709 let result = v.resolve_length(Length::from_pt(200.0));
710 assert_eq!(result, Some(Length::from_pt(50.0)));
711 }
712
713 #[test]
714 fn test_resolve_length_with_auto_returns_none() {
715 let v = PropertyValue::Auto;
716 let result = v.resolve_length(Length::from_pt(100.0));
717 assert!(result.is_none());
718 }
719
720 #[test]
721 fn test_resolve_length_with_none_returns_none() {
722 let v = PropertyValue::None;
723 let result = v.resolve_length(Length::from_pt(100.0));
724 assert!(result.is_none());
725 }
726
727 #[test]
730 fn test_relative_font_size_parse_all_keywords() {
731 assert!(RelativeFontSize::parse("larger").is_some());
732 assert!(RelativeFontSize::parse("smaller").is_some());
733 assert!(RelativeFontSize::parse("xx-small").is_some());
734 assert!(RelativeFontSize::parse("x-small").is_some());
735 assert!(RelativeFontSize::parse("small").is_some());
736 assert!(RelativeFontSize::parse("medium").is_some());
737 assert!(RelativeFontSize::parse("large").is_some());
738 assert!(RelativeFontSize::parse("x-large").is_some());
739 assert!(RelativeFontSize::parse("xx-large").is_some());
740 }
741
742 #[test]
743 fn test_relative_font_size_parse_invalid_returns_none() {
744 assert!(RelativeFontSize::parse("").is_none());
745 assert!(RelativeFontSize::parse("LARGE").is_none());
746 assert!(RelativeFontSize::parse("12pt").is_none());
747 assert!(RelativeFontSize::parse("unknown").is_none());
748 }
749
750 #[test]
751 fn test_relative_font_size_is_relative_for_larger_smaller() {
752 assert!(RelativeFontSize::Larger.is_relative());
753 assert!(RelativeFontSize::Smaller.is_relative());
754 assert!(!RelativeFontSize::Medium.is_relative());
755 assert!(!RelativeFontSize::Large.is_relative());
756 }
757
758 #[test]
759 fn test_relative_font_size_is_absolute_keyword() {
760 assert!(RelativeFontSize::XxSmall.is_absolute_keyword());
761 assert!(RelativeFontSize::XSmall.is_absolute_keyword());
762 assert!(RelativeFontSize::Small.is_absolute_keyword());
763 assert!(RelativeFontSize::Medium.is_absolute_keyword());
764 assert!(RelativeFontSize::Large.is_absolute_keyword());
765 assert!(RelativeFontSize::XLarge.is_absolute_keyword());
766 assert!(RelativeFontSize::XxLarge.is_absolute_keyword());
767 assert!(!RelativeFontSize::Larger.is_absolute_keyword());
768 assert!(!RelativeFontSize::Smaller.is_absolute_keyword());
769 }
770
771 #[test]
772 fn test_relative_font_size_resolve_xx_small() {
773 let result = RelativeFontSize::XxSmall.resolve(Length::from_pt(16.0));
774 assert_eq!(result, Length::from_pt(9.0));
775 }
776
777 #[test]
778 fn test_relative_font_size_resolve_xx_large() {
779 let result = RelativeFontSize::XxLarge.resolve(Length::from_pt(16.0));
780 assert_eq!(result, Length::from_pt(32.0));
781 }
782
783 #[test]
784 fn test_relative_font_size_larger_increases() {
785 let parent = Length::from_pt(10.0);
786 let result = RelativeFontSize::Larger.resolve(parent);
787 assert!(result.millipoints() > parent.millipoints());
788 }
789
790 #[test]
791 fn test_relative_font_size_smaller_decreases() {
792 let parent = Length::from_pt(10.0);
793 let result = RelativeFontSize::Smaller.resolve(parent);
794 assert!(result.millipoints() < parent.millipoints());
795 }
796
797 #[test]
800 fn test_property_value_equality_auto() {
801 assert_eq!(PropertyValue::Auto, PropertyValue::Auto);
802 }
803
804 #[test]
805 fn test_property_value_equality_none() {
806 assert_eq!(PropertyValue::None, PropertyValue::None);
807 }
808
809 #[test]
810 fn test_property_value_equality_inherit() {
811 assert_eq!(PropertyValue::Inherit, PropertyValue::Inherit);
812 }
813
814 #[test]
815 fn test_property_value_equality_integer() {
816 assert_eq!(PropertyValue::Integer(42), PropertyValue::Integer(42));
817 assert_ne!(PropertyValue::Integer(42), PropertyValue::Integer(43));
818 }
819
820 #[test]
821 fn test_property_value_inequality_different_types() {
822 assert_ne!(PropertyValue::Auto, PropertyValue::None);
823 assert_ne!(PropertyValue::None, PropertyValue::Inherit);
824 assert_ne!(PropertyValue::Integer(0), PropertyValue::Boolean(false));
825 }
826}