1use core::fmt;
12
13#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
28#[non_exhaustive]
29pub enum UnsupportedOperation {
30 RowLevelEncode,
32 PullEncode,
34 AnimationEncode,
36 DecodeInto,
38 RowLevelDecode,
40 AnimationDecode,
42 PixelFormat,
44 MultiImageDecode,
46}
47
48impl UnsupportedOperation {
49 pub const fn name(self) -> &'static str {
51 match self {
52 Self::RowLevelEncode => "row_level_encode",
53 Self::PullEncode => "pull_encode",
54 Self::AnimationEncode => "animation_encode",
55 Self::DecodeInto => "decode_into",
56 Self::RowLevelDecode => "row_level_decode",
57 Self::AnimationDecode => "animation_decode",
58 Self::PixelFormat => "pixel_format",
59 Self::MultiImageDecode => "multi_image_decode",
60 }
61 }
62}
63
64impl fmt::Display for UnsupportedOperation {
65 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66 write!(f, "unsupported operation: {}", self.name())
67 }
68}
69
70impl core::error::Error for UnsupportedOperation {}
71
72#[derive(Clone, PartialEq)]
98#[non_exhaustive]
99pub struct EncodeCapabilities {
100 icc: bool,
102 exif: bool,
103 xmp: bool,
104 cicp: bool,
105 stop: bool,
107 animation: bool,
108 push_rows: bool,
109 encode_from: bool,
110 lossy: bool,
112 lossless: bool,
113 hdr: bool,
114 gain_map: bool,
115 native_gray: bool,
116 native_16bit: bool,
117 native_f32: bool,
118 native_alpha: bool,
119 enforces_max_pixels: bool,
121 enforces_max_memory: bool,
122 effort_range: Option<[i32; 2]>,
124 quality_range: Option<[f32; 2]>,
125 threads_supported_range: (u16, u16),
127}
128
129impl Default for EncodeCapabilities {
130 fn default() -> Self {
131 Self::new()
132 }
133}
134
135impl EncodeCapabilities {
136 pub const EMPTY: Self = Self::new();
138
139 pub const fn new() -> Self {
141 Self {
142 icc: false,
143 exif: false,
144 xmp: false,
145 cicp: false,
146 stop: false,
147 animation: false,
148 push_rows: false,
149 encode_from: false,
150 lossy: false,
151 lossless: false,
152 hdr: false,
153 gain_map: false,
154 native_gray: false,
155 native_16bit: false,
156 native_f32: false,
157 native_alpha: false,
158 enforces_max_pixels: false,
159 enforces_max_memory: false,
160 effort_range: None,
161 quality_range: None,
162 threads_supported_range: (1, 1),
163 }
164 }
165
166 pub const fn icc(&self) -> bool {
170 self.icc
171 }
172 pub const fn exif(&self) -> bool {
174 self.exif
175 }
176 pub const fn xmp(&self) -> bool {
178 self.xmp
179 }
180 pub const fn cicp(&self) -> bool {
182 self.cicp
183 }
184 pub const fn stop(&self) -> bool {
186 self.stop
187 }
188 pub const fn animation(&self) -> bool {
190 self.animation
191 }
192 pub const fn push_rows(&self) -> bool {
194 self.push_rows
195 }
196 pub const fn encode_from(&self) -> bool {
198 self.encode_from
199 }
200 pub const fn lossy(&self) -> bool {
202 self.lossy
203 }
204 pub const fn lossless(&self) -> bool {
206 self.lossless
207 }
208 pub const fn hdr(&self) -> bool {
210 self.hdr
211 }
212 pub const fn gain_map(&self) -> bool {
214 self.gain_map
215 }
216 pub const fn native_gray(&self) -> bool {
218 self.native_gray
219 }
220 pub const fn native_16bit(&self) -> bool {
222 self.native_16bit
223 }
224 pub const fn native_f32(&self) -> bool {
226 self.native_f32
227 }
228 pub const fn native_alpha(&self) -> bool {
230 self.native_alpha
231 }
232 pub const fn enforces_max_pixels(&self) -> bool {
234 self.enforces_max_pixels
235 }
236 pub const fn enforces_max_memory(&self) -> bool {
238 self.enforces_max_memory
239 }
240
241 pub const fn effort_range(&self) -> Option<[i32; 2]> {
245 self.effort_range
246 }
247
248 pub const fn quality_range(&self) -> Option<[f32; 2]> {
252 self.quality_range
253 }
254
255 pub const fn threads_supported_range(&self) -> (u16, u16) {
260 self.threads_supported_range
261 }
262
263 pub const fn supports(&self, op: UnsupportedOperation) -> bool {
285 match op {
286 UnsupportedOperation::RowLevelEncode => self.push_rows,
287 UnsupportedOperation::PullEncode => self.encode_from,
288 UnsupportedOperation::AnimationEncode => self.animation,
289 UnsupportedOperation::DecodeInto
290 | UnsupportedOperation::RowLevelDecode
291 | UnsupportedOperation::AnimationDecode
292 | UnsupportedOperation::MultiImageDecode
293 | UnsupportedOperation::PixelFormat => false,
294 }
295 }
296
297 pub const fn with_icc(mut self, v: bool) -> Self {
301 self.icc = v;
302 self
303 }
304 pub const fn with_exif(mut self, v: bool) -> Self {
306 self.exif = v;
307 self
308 }
309 pub const fn with_xmp(mut self, v: bool) -> Self {
311 self.xmp = v;
312 self
313 }
314 pub const fn with_cicp(mut self, v: bool) -> Self {
316 self.cicp = v;
317 self
318 }
319 pub const fn with_stop(mut self, v: bool) -> Self {
321 self.stop = v;
322 self
323 }
324 pub const fn with_animation(mut self, v: bool) -> Self {
326 self.animation = v;
327 self
328 }
329 pub const fn with_push_rows(mut self, v: bool) -> Self {
331 self.push_rows = v;
332 self
333 }
334 pub const fn with_encode_from(mut self, v: bool) -> Self {
336 self.encode_from = v;
337 self
338 }
339 pub const fn with_lossy(mut self, v: bool) -> Self {
341 self.lossy = v;
342 self
343 }
344 pub const fn with_lossless(mut self, v: bool) -> Self {
346 self.lossless = v;
347 self
348 }
349 pub const fn with_hdr(mut self, v: bool) -> Self {
351 self.hdr = v;
352 self
353 }
354 pub const fn with_gain_map(mut self, v: bool) -> Self {
356 self.gain_map = v;
357 self
358 }
359 pub const fn with_native_gray(mut self, v: bool) -> Self {
361 self.native_gray = v;
362 self
363 }
364 pub const fn with_native_16bit(mut self, v: bool) -> Self {
366 self.native_16bit = v;
367 self
368 }
369 pub const fn with_native_f32(mut self, v: bool) -> Self {
371 self.native_f32 = v;
372 self
373 }
374 pub const fn with_native_alpha(mut self, v: bool) -> Self {
376 self.native_alpha = v;
377 self
378 }
379 pub const fn with_enforces_max_pixels(mut self, v: bool) -> Self {
381 self.enforces_max_pixels = v;
382 self
383 }
384 pub const fn with_enforces_max_memory(mut self, v: bool) -> Self {
386 self.enforces_max_memory = v;
387 self
388 }
389
390 pub const fn with_effort_range(mut self, min: i32, max: i32) -> Self {
392 assert!(min <= max, "effort range: min must be <= max");
393 self.effort_range = Some([min, max]);
394 self
395 }
396
397 pub const fn with_quality_range(mut self, min: f32, max: f32) -> Self {
399 assert!(min <= max, "quality range: min must be <= max");
400 self.quality_range = Some([min, max]);
401 self
402 }
403
404 pub const fn with_threads_supported_range(mut self, min: u16, max: u16) -> Self {
406 assert!(min >= 1, "threads range: min must be >= 1");
407 assert!(min <= max, "threads range: min must be <= max");
408 self.threads_supported_range = (min, max);
409 self
410 }
411}
412
413impl fmt::Debug for EncodeCapabilities {
414 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
415 let mut s = f.debug_struct("EncodeCapabilities");
416 s.field("icc", &self.icc)
417 .field("exif", &self.exif)
418 .field("xmp", &self.xmp)
419 .field("cicp", &self.cicp)
420 .field("stop", &self.stop)
421 .field("animation", &self.animation)
422 .field("lossy", &self.lossy)
423 .field("lossless", &self.lossless)
424 .field("hdr", &self.hdr)
425 .field("gain_map", &self.gain_map)
426 .field("native_gray", &self.native_gray)
427 .field("native_16bit", &self.native_16bit)
428 .field("native_f32", &self.native_f32)
429 .field("native_alpha", &self.native_alpha)
430 .field("push_rows", &self.push_rows)
431 .field("encode_from", &self.encode_from)
432 .field("enforces_max_pixels", &self.enforces_max_pixels)
433 .field("enforces_max_memory", &self.enforces_max_memory)
434 .field("threads_supported_range", &self.threads_supported_range);
435 if let Some(range) = &self.effort_range {
436 s.field("effort_range", range);
437 }
438 if let Some(range) = &self.quality_range {
439 s.field("quality_range", range);
440 }
441 s.finish()
442 }
443}
444
445#[derive(Clone, PartialEq, Eq)]
470#[non_exhaustive]
471pub struct DecodeCapabilities {
472 icc: bool,
474 exif: bool,
475 xmp: bool,
476 cicp: bool,
477 stop: bool,
479 animation: bool,
480 multi_image: bool,
481 cheap_probe: bool,
482 decode_into: bool,
483 streaming: bool,
484 hdr: bool,
486 gain_map: bool,
487 native_gray: bool,
488 native_16bit: bool,
489 native_f32: bool,
490 native_alpha: bool,
491 enforces_max_pixels: bool,
493 enforces_max_memory: bool,
494 enforces_max_input_bytes: bool,
495 threads_supported_range: (u16, u16),
497}
498
499impl Default for DecodeCapabilities {
500 fn default() -> Self {
501 Self::new()
502 }
503}
504
505impl DecodeCapabilities {
506 pub const EMPTY: Self = Self::new();
508
509 pub const fn new() -> Self {
511 Self {
512 icc: false,
513 exif: false,
514 xmp: false,
515 cicp: false,
516 stop: false,
517 animation: false,
518 multi_image: false,
519 cheap_probe: false,
520 decode_into: false,
521 streaming: false,
522 hdr: false,
523 gain_map: false,
524 native_gray: false,
525 native_16bit: false,
526 native_f32: false,
527 native_alpha: false,
528 enforces_max_pixels: false,
529 enforces_max_memory: false,
530 enforces_max_input_bytes: false,
531 threads_supported_range: (1, 1),
532 }
533 }
534
535 pub const fn icc(&self) -> bool {
539 self.icc
540 }
541 pub const fn exif(&self) -> bool {
543 self.exif
544 }
545 pub const fn xmp(&self) -> bool {
547 self.xmp
548 }
549 pub const fn cicp(&self) -> bool {
551 self.cicp
552 }
553 pub const fn stop(&self) -> bool {
555 self.stop
556 }
557 pub const fn animation(&self) -> bool {
559 self.animation
560 }
561 pub const fn multi_image(&self) -> bool {
566 self.multi_image
567 }
568 pub const fn cheap_probe(&self) -> bool {
570 self.cheap_probe
571 }
572 pub const fn decode_into(&self) -> bool {
574 self.decode_into
575 }
576 pub const fn streaming(&self) -> bool {
578 self.streaming
579 }
580 pub const fn hdr(&self) -> bool {
582 self.hdr
583 }
584 pub const fn gain_map(&self) -> bool {
586 self.gain_map
587 }
588 pub const fn native_gray(&self) -> bool {
590 self.native_gray
591 }
592 pub const fn native_16bit(&self) -> bool {
594 self.native_16bit
595 }
596 pub const fn native_f32(&self) -> bool {
598 self.native_f32
599 }
600 pub const fn native_alpha(&self) -> bool {
602 self.native_alpha
603 }
604 pub const fn enforces_max_pixels(&self) -> bool {
606 self.enforces_max_pixels
607 }
608 pub const fn enforces_max_memory(&self) -> bool {
610 self.enforces_max_memory
611 }
612 pub const fn enforces_max_input_bytes(&self) -> bool {
614 self.enforces_max_input_bytes
615 }
616
617 pub const fn threads_supported_range(&self) -> (u16, u16) {
622 self.threads_supported_range
623 }
624
625 pub const fn supports(&self, op: UnsupportedOperation) -> bool {
647 match op {
648 UnsupportedOperation::DecodeInto => self.decode_into,
649 UnsupportedOperation::RowLevelDecode => self.streaming,
650 UnsupportedOperation::AnimationDecode => self.animation,
651 UnsupportedOperation::MultiImageDecode => self.multi_image,
652 UnsupportedOperation::RowLevelEncode
653 | UnsupportedOperation::PullEncode
654 | UnsupportedOperation::AnimationEncode
655 | UnsupportedOperation::PixelFormat => false,
656 }
657 }
658
659 pub const fn with_icc(mut self, v: bool) -> Self {
663 self.icc = v;
664 self
665 }
666 pub const fn with_exif(mut self, v: bool) -> Self {
668 self.exif = v;
669 self
670 }
671 pub const fn with_xmp(mut self, v: bool) -> Self {
673 self.xmp = v;
674 self
675 }
676 pub const fn with_cicp(mut self, v: bool) -> Self {
678 self.cicp = v;
679 self
680 }
681 pub const fn with_stop(mut self, v: bool) -> Self {
683 self.stop = v;
684 self
685 }
686 pub const fn with_animation(mut self, v: bool) -> Self {
688 self.animation = v;
689 self
690 }
691 pub const fn with_multi_image(mut self, v: bool) -> Self {
693 self.multi_image = v;
694 self
695 }
696 pub const fn with_cheap_probe(mut self, v: bool) -> Self {
698 self.cheap_probe = v;
699 self
700 }
701 pub const fn with_decode_into(mut self, v: bool) -> Self {
703 self.decode_into = v;
704 self
705 }
706 pub const fn with_streaming(mut self, v: bool) -> Self {
708 self.streaming = v;
709 self
710 }
711 pub const fn with_hdr(mut self, v: bool) -> Self {
713 self.hdr = v;
714 self
715 }
716 pub const fn with_gain_map(mut self, v: bool) -> Self {
718 self.gain_map = v;
719 self
720 }
721 pub const fn with_native_gray(mut self, v: bool) -> Self {
723 self.native_gray = v;
724 self
725 }
726 pub const fn with_native_16bit(mut self, v: bool) -> Self {
728 self.native_16bit = v;
729 self
730 }
731 pub const fn with_native_f32(mut self, v: bool) -> Self {
733 self.native_f32 = v;
734 self
735 }
736 pub const fn with_native_alpha(mut self, v: bool) -> Self {
738 self.native_alpha = v;
739 self
740 }
741 pub const fn with_enforces_max_pixels(mut self, v: bool) -> Self {
743 self.enforces_max_pixels = v;
744 self
745 }
746 pub const fn with_enforces_max_memory(mut self, v: bool) -> Self {
748 self.enforces_max_memory = v;
749 self
750 }
751 pub const fn with_enforces_max_input_bytes(mut self, v: bool) -> Self {
753 self.enforces_max_input_bytes = v;
754 self
755 }
756
757 pub const fn with_threads_supported_range(mut self, min: u16, max: u16) -> Self {
759 assert!(min >= 1, "threads range: min must be >= 1");
760 assert!(min <= max, "threads range: min must be <= max");
761 self.threads_supported_range = (min, max);
762 self
763 }
764}
765
766impl fmt::Debug for DecodeCapabilities {
767 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
768 let mut s = f.debug_struct("DecodeCapabilities");
769 s.field("icc", &self.icc)
770 .field("exif", &self.exif)
771 .field("xmp", &self.xmp)
772 .field("cicp", &self.cicp)
773 .field("stop", &self.stop)
774 .field("animation", &self.animation)
775 .field("multi_image", &self.multi_image)
776 .field("cheap_probe", &self.cheap_probe)
777 .field("decode_into", &self.decode_into)
778 .field("streaming", &self.streaming)
779 .field("hdr", &self.hdr)
780 .field("gain_map", &self.gain_map)
781 .field("native_gray", &self.native_gray)
782 .field("native_16bit", &self.native_16bit)
783 .field("native_f32", &self.native_f32)
784 .field("native_alpha", &self.native_alpha)
785 .field("enforces_max_pixels", &self.enforces_max_pixels)
786 .field("enforces_max_memory", &self.enforces_max_memory)
787 .field("enforces_max_input_bytes", &self.enforces_max_input_bytes)
788 .field("threads_supported_range", &self.threads_supported_range);
789 s.finish()
790 }
791}
792
793#[cfg(test)]
794mod tests {
795 use super::*;
796
797 #[test]
798 fn encode_default_all_false() {
799 let caps = EncodeCapabilities::new();
800 assert!(!caps.icc());
801 assert!(!caps.exif());
802 assert!(!caps.xmp());
803 assert!(!caps.cicp());
804 assert!(!caps.stop());
805 assert!(!caps.animation());
806 assert!(!caps.push_rows());
807 assert!(!caps.encode_from());
808 assert!(!caps.lossy());
809 assert!(!caps.lossless());
810 assert!(!caps.hdr());
811 assert!(!caps.native_gray());
812 assert!(!caps.native_16bit());
813 assert!(!caps.native_f32());
814 assert!(!caps.native_alpha());
815 assert!(!caps.enforces_max_pixels());
816 assert!(!caps.enforces_max_memory());
817 assert!(caps.effort_range().is_none());
818 assert!(caps.quality_range().is_none());
819 assert_eq!(caps.threads_supported_range(), (1, 1));
820 }
821
822 #[test]
823 fn decode_default_all_false() {
824 let caps = DecodeCapabilities::new();
825 assert!(!caps.icc());
826 assert!(!caps.exif());
827 assert!(!caps.xmp());
828 assert!(!caps.cicp());
829 assert!(!caps.stop());
830 assert!(!caps.animation());
831 assert!(!caps.cheap_probe());
832 assert!(!caps.decode_into());
833 assert!(!caps.streaming());
834 assert!(!caps.hdr());
835 assert!(!caps.native_gray());
836 assert!(!caps.native_16bit());
837 assert!(!caps.native_f32());
838 assert!(!caps.native_alpha());
839 assert!(!caps.enforces_max_pixels());
840 assert!(!caps.enforces_max_memory());
841 assert!(!caps.enforces_max_input_bytes());
842 assert_eq!(caps.threads_supported_range(), (1, 1));
843 }
844
845 #[test]
846 fn encode_builder() {
847 let caps = EncodeCapabilities::new()
848 .with_icc(true)
849 .with_stop(true)
850 .with_native_gray(true)
851 .with_animation(true)
852 .with_native_16bit(true)
853 .with_hdr(true)
854 .with_threads_supported_range(1, 8);
855 assert!(caps.icc());
856 assert!(!caps.exif());
857 assert!(caps.stop());
858 assert!(caps.native_gray());
859 assert!(caps.animation());
860 assert!(caps.native_16bit());
861 assert!(!caps.lossless());
862 assert!(caps.hdr());
863 assert_eq!(caps.threads_supported_range(), (1, 8));
864 }
865
866 #[test]
867 fn decode_builder() {
868 let caps = DecodeCapabilities::new()
869 .with_icc(true)
870 .with_cheap_probe(true)
871 .with_stop(true)
872 .with_animation(true)
873 .with_enforces_max_input_bytes(true)
874 .with_threads_supported_range(1, 4);
875 assert!(caps.icc());
876 assert!(caps.cheap_probe());
877 assert!(caps.stop());
878 assert!(caps.animation());
879 assert!(caps.enforces_max_input_bytes());
880 assert_eq!(caps.threads_supported_range(), (1, 4));
881 }
882
883 #[test]
884 fn encode_static_construction() {
885 static CAPS: EncodeCapabilities = EncodeCapabilities::new()
886 .with_icc(true)
887 .with_exif(true)
888 .with_xmp(true)
889 .with_stop(true)
890 .with_animation(true)
891 .with_lossless(true)
892 .with_cicp(true)
893 .with_effort_range(0, 100)
894 .with_quality_range(0.0, 100.0)
895 .with_threads_supported_range(1, 16);
896 assert!(CAPS.icc());
897 assert!(CAPS.stop());
898 assert!(!CAPS.native_gray());
899 assert!(CAPS.animation());
900 assert!(CAPS.lossless());
901 assert!(CAPS.cicp());
902 assert_eq!(CAPS.effort_range(), Some([0, 100]));
903 assert_eq!(CAPS.quality_range(), Some([0.0, 100.0]));
904 assert_eq!(CAPS.threads_supported_range(), (1, 16));
905 }
906
907 #[test]
908 fn decode_static_construction() {
909 static CAPS: DecodeCapabilities = DecodeCapabilities::new()
910 .with_icc(true)
911 .with_cheap_probe(true)
912 .with_stop(true)
913 .with_animation(true)
914 .with_enforces_max_pixels(true)
915 .with_enforces_max_input_bytes(true);
916 assert!(CAPS.icc());
917 assert!(CAPS.cheap_probe());
918 assert!(CAPS.enforces_max_pixels());
919 assert!(!CAPS.enforces_max_memory());
920 assert!(CAPS.enforces_max_input_bytes());
921 }
922
923 #[test]
924 fn encode_effort_quality_ranges() {
925 let caps = EncodeCapabilities::new()
926 .with_effort_range(0, 10)
927 .with_quality_range(0.0, 100.0);
928 assert_eq!(caps.effort_range(), Some([0i32, 10]));
929 assert_eq!(caps.quality_range(), Some([0.0, 100.0]));
930 }
931
932 #[test]
933 fn encode_supports() {
934 let caps = EncodeCapabilities::new()
935 .with_push_rows(true)
936 .with_encode_from(true)
937 .with_animation(true);
938 assert!(caps.supports(UnsupportedOperation::RowLevelEncode));
939 assert!(caps.supports(UnsupportedOperation::PullEncode));
940 assert!(caps.supports(UnsupportedOperation::AnimationEncode));
941 assert!(!caps.supports(UnsupportedOperation::DecodeInto));
942 assert!(!caps.supports(UnsupportedOperation::RowLevelDecode));
943 assert!(!caps.supports(UnsupportedOperation::AnimationDecode));
944 assert!(!caps.supports(UnsupportedOperation::PixelFormat));
945 }
946
947 #[test]
948 fn decode_supports() {
949 let caps = DecodeCapabilities::new()
950 .with_decode_into(true)
951 .with_streaming(true)
952 .with_animation(true);
953 assert!(caps.supports(UnsupportedOperation::DecodeInto));
954 assert!(caps.supports(UnsupportedOperation::RowLevelDecode));
955 assert!(caps.supports(UnsupportedOperation::AnimationDecode));
956 assert!(!caps.supports(UnsupportedOperation::RowLevelEncode));
957 assert!(!caps.supports(UnsupportedOperation::PullEncode));
958 assert!(!caps.supports(UnsupportedOperation::AnimationEncode));
959 assert!(!caps.supports(UnsupportedOperation::PixelFormat));
960 }
961
962 #[test]
963 fn supports_empty_all_false() {
964 let enc = EncodeCapabilities::new();
965 let dec = DecodeCapabilities::new();
966 for op in [
967 UnsupportedOperation::RowLevelEncode,
968 UnsupportedOperation::PullEncode,
969 UnsupportedOperation::AnimationEncode,
970 UnsupportedOperation::DecodeInto,
971 UnsupportedOperation::RowLevelDecode,
972 UnsupportedOperation::AnimationDecode,
973 UnsupportedOperation::PixelFormat,
974 ] {
975 assert!(
976 !enc.supports(op),
977 "EncodeCapabilities::EMPTY.supports({op:?})"
978 );
979 assert!(
980 !dec.supports(op),
981 "DecodeCapabilities::EMPTY.supports({op:?})"
982 );
983 }
984 }
985
986 #[test]
987 fn unsupported_operation_display() {
988 assert_eq!(
989 alloc::format!("{}", UnsupportedOperation::RowLevelEncode),
990 "unsupported operation: row_level_encode"
991 );
992 assert_eq!(
993 alloc::format!("{}", UnsupportedOperation::DecodeInto),
994 "unsupported operation: decode_into"
995 );
996 assert_eq!(
997 alloc::format!("{}", UnsupportedOperation::PixelFormat),
998 "unsupported operation: pixel_format"
999 );
1000 }
1001
1002 #[test]
1003 fn unsupported_operation_name() {
1004 assert_eq!(UnsupportedOperation::PullEncode.name(), "pull_encode");
1005 assert_eq!(
1006 UnsupportedOperation::AnimationEncode.name(),
1007 "animation_encode"
1008 );
1009 assert_eq!(
1010 UnsupportedOperation::RowLevelDecode.name(),
1011 "row_level_decode"
1012 );
1013 assert_eq!(
1014 UnsupportedOperation::AnimationDecode.name(),
1015 "animation_decode"
1016 );
1017 }
1018
1019 #[test]
1020 fn unsupported_operation_is_error() {
1021 let op = UnsupportedOperation::DecodeInto;
1022 let err: &dyn core::error::Error = &op;
1023 assert!(err.source().is_none());
1024 }
1025
1026 #[test]
1027 fn unsupported_operation_eq_hash() {
1028 assert_eq!(
1029 UnsupportedOperation::DecodeInto,
1030 UnsupportedOperation::DecodeInto
1031 );
1032 assert_ne!(
1033 UnsupportedOperation::DecodeInto,
1034 UnsupportedOperation::PullEncode
1035 );
1036 }
1037}