1use std::path::PathBuf;
2
3use bitflags::bitflags;
4use serde::{Deserialize, Serialize};
5
6use crate::common::FileType;
7
8#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
10pub struct Metadata {
11 #[serde(default, skip_serializing_if = "Option::is_none")]
14 pub canonicalized_path: Option<PathBuf>,
15
16 pub file_type: FileType,
18
19 pub len: u64,
21
22 pub readonly: bool,
24
25 #[serde(default, skip_serializing_if = "Option::is_none")]
28 pub accessed: Option<u64>,
29
30 #[serde(default, skip_serializing_if = "Option::is_none")]
33 pub created: Option<u64>,
34
35 #[serde(default, skip_serializing_if = "Option::is_none")]
38 pub modified: Option<u64>,
39
40 #[serde(default, skip_serializing_if = "Option::is_none")]
42 pub unix: Option<UnixMetadata>,
43
44 #[serde(default, skip_serializing_if = "Option::is_none")]
46 pub windows: Option<WindowsMetadata>,
47}
48
49#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
51pub struct UnixMetadata {
52 pub owner_read: bool,
54
55 pub owner_write: bool,
57
58 pub owner_exec: bool,
60
61 pub group_read: bool,
63
64 pub group_write: bool,
66
67 pub group_exec: bool,
69
70 pub other_read: bool,
72
73 pub other_write: bool,
75
76 pub other_exec: bool,
78}
79
80impl From<u32> for UnixMetadata {
81 fn from(mode: u32) -> Self {
83 let flags = UnixFilePermissionFlags::from_bits_truncate(mode);
84 Self {
85 owner_read: flags.contains(UnixFilePermissionFlags::OWNER_READ),
86 owner_write: flags.contains(UnixFilePermissionFlags::OWNER_WRITE),
87 owner_exec: flags.contains(UnixFilePermissionFlags::OWNER_EXEC),
88 group_read: flags.contains(UnixFilePermissionFlags::GROUP_READ),
89 group_write: flags.contains(UnixFilePermissionFlags::GROUP_WRITE),
90 group_exec: flags.contains(UnixFilePermissionFlags::GROUP_EXEC),
91 other_read: flags.contains(UnixFilePermissionFlags::OTHER_READ),
92 other_write: flags.contains(UnixFilePermissionFlags::OTHER_WRITE),
93 other_exec: flags.contains(UnixFilePermissionFlags::OTHER_EXEC),
94 }
95 }
96}
97
98impl From<UnixMetadata> for u32 {
99 fn from(metadata: UnixMetadata) -> Self {
101 let mut flags = UnixFilePermissionFlags::empty();
102
103 if metadata.owner_read {
104 flags.insert(UnixFilePermissionFlags::OWNER_READ);
105 }
106 if metadata.owner_write {
107 flags.insert(UnixFilePermissionFlags::OWNER_WRITE);
108 }
109 if metadata.owner_exec {
110 flags.insert(UnixFilePermissionFlags::OWNER_EXEC);
111 }
112
113 if metadata.group_read {
114 flags.insert(UnixFilePermissionFlags::GROUP_READ);
115 }
116 if metadata.group_write {
117 flags.insert(UnixFilePermissionFlags::GROUP_WRITE);
118 }
119 if metadata.group_exec {
120 flags.insert(UnixFilePermissionFlags::GROUP_EXEC);
121 }
122
123 if metadata.other_read {
124 flags.insert(UnixFilePermissionFlags::OTHER_READ);
125 }
126 if metadata.other_write {
127 flags.insert(UnixFilePermissionFlags::OTHER_WRITE);
128 }
129 if metadata.other_exec {
130 flags.insert(UnixFilePermissionFlags::OTHER_EXEC);
131 }
132
133 flags.bits()
134 }
135}
136
137impl UnixMetadata {
138 pub fn is_readonly(self) -> bool {
139 !(self.owner_write || self.group_write || self.other_write)
140 }
141}
142
143bitflags! {
144 struct UnixFilePermissionFlags: u32 {
145 const OWNER_READ = 0o400;
146 const OWNER_WRITE = 0o200;
147 const OWNER_EXEC = 0o100;
148 const GROUP_READ = 0o40;
149 const GROUP_WRITE = 0o20;
150 const GROUP_EXEC = 0o10;
151 const OTHER_READ = 0o4;
152 const OTHER_WRITE = 0o2;
153 const OTHER_EXEC = 0o1;
154 }
155}
156
157#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
159pub struct WindowsMetadata {
160 pub archive: bool,
162
163 pub compressed: bool,
165
166 pub encrypted: bool,
168
169 pub hidden: bool,
171
172 pub integrity_stream: bool,
174
175 pub normal: bool,
177
178 pub not_content_indexed: bool,
181
182 pub no_scrub_data: bool,
185
186 pub offline: bool,
188
189 pub recall_on_data_access: bool,
191
192 pub recall_on_open: bool,
195
196 pub reparse_point: bool,
199
200 pub sparse_file: bool,
202
203 pub system: bool,
206
207 pub temporary: bool,
209}
210
211impl From<u32> for WindowsMetadata {
212 fn from(file_attributes: u32) -> Self {
214 let flags = WindowsFileAttributeFlags::from_bits_truncate(file_attributes);
215 Self {
216 archive: flags.contains(WindowsFileAttributeFlags::ARCHIVE),
217 compressed: flags.contains(WindowsFileAttributeFlags::COMPRESSED),
218 encrypted: flags.contains(WindowsFileAttributeFlags::ENCRYPTED),
219 hidden: flags.contains(WindowsFileAttributeFlags::HIDDEN),
220 integrity_stream: flags.contains(WindowsFileAttributeFlags::INTEGRITY_SYSTEM),
221 normal: flags.contains(WindowsFileAttributeFlags::NORMAL),
222 not_content_indexed: flags.contains(WindowsFileAttributeFlags::NOT_CONTENT_INDEXED),
223 no_scrub_data: flags.contains(WindowsFileAttributeFlags::NO_SCRUB_DATA),
224 offline: flags.contains(WindowsFileAttributeFlags::OFFLINE),
225 recall_on_data_access: flags.contains(WindowsFileAttributeFlags::RECALL_ON_DATA_ACCESS),
226 recall_on_open: flags.contains(WindowsFileAttributeFlags::RECALL_ON_OPEN),
227 reparse_point: flags.contains(WindowsFileAttributeFlags::REPARSE_POINT),
228 sparse_file: flags.contains(WindowsFileAttributeFlags::SPARSE_FILE),
229 system: flags.contains(WindowsFileAttributeFlags::SYSTEM),
230 temporary: flags.contains(WindowsFileAttributeFlags::TEMPORARY),
231 }
232 }
233}
234
235impl From<WindowsMetadata> for u32 {
236 fn from(metadata: WindowsMetadata) -> Self {
238 let mut flags = WindowsFileAttributeFlags::empty();
239
240 if metadata.archive {
241 flags.insert(WindowsFileAttributeFlags::ARCHIVE);
242 }
243 if metadata.compressed {
244 flags.insert(WindowsFileAttributeFlags::COMPRESSED);
245 }
246 if metadata.encrypted {
247 flags.insert(WindowsFileAttributeFlags::ENCRYPTED);
248 }
249 if metadata.hidden {
250 flags.insert(WindowsFileAttributeFlags::HIDDEN);
251 }
252 if metadata.integrity_stream {
253 flags.insert(WindowsFileAttributeFlags::INTEGRITY_SYSTEM);
254 }
255 if metadata.normal {
256 flags.insert(WindowsFileAttributeFlags::NORMAL);
257 }
258 if metadata.not_content_indexed {
259 flags.insert(WindowsFileAttributeFlags::NOT_CONTENT_INDEXED);
260 }
261 if metadata.no_scrub_data {
262 flags.insert(WindowsFileAttributeFlags::NO_SCRUB_DATA);
263 }
264 if metadata.offline {
265 flags.insert(WindowsFileAttributeFlags::OFFLINE);
266 }
267 if metadata.recall_on_data_access {
268 flags.insert(WindowsFileAttributeFlags::RECALL_ON_DATA_ACCESS);
269 }
270 if metadata.recall_on_open {
271 flags.insert(WindowsFileAttributeFlags::RECALL_ON_OPEN);
272 }
273 if metadata.reparse_point {
274 flags.insert(WindowsFileAttributeFlags::REPARSE_POINT);
275 }
276 if metadata.sparse_file {
277 flags.insert(WindowsFileAttributeFlags::SPARSE_FILE);
278 }
279 if metadata.system {
280 flags.insert(WindowsFileAttributeFlags::SYSTEM);
281 }
282 if metadata.temporary {
283 flags.insert(WindowsFileAttributeFlags::TEMPORARY);
284 }
285
286 flags.bits()
287 }
288}
289
290bitflags! {
291 struct WindowsFileAttributeFlags: u32 {
292 const ARCHIVE = 0x20;
293 const COMPRESSED = 0x800;
294 const ENCRYPTED = 0x4000;
295 const HIDDEN = 0x2;
296 const INTEGRITY_SYSTEM = 0x8000;
297 const NORMAL = 0x80;
298 const NOT_CONTENT_INDEXED = 0x2000;
299 const NO_SCRUB_DATA = 0x20000;
300 const OFFLINE = 0x1000;
301 const RECALL_ON_DATA_ACCESS = 0x400000;
302 const RECALL_ON_OPEN = 0x40000;
303 const REPARSE_POINT = 0x400;
304 const SPARSE_FILE = 0x200;
305 const SYSTEM = 0x4;
306 const TEMPORARY = 0x100;
307 const VIRTUAL = 0x10000;
308 }
309}
310
311#[cfg(test)]
312mod tests {
313 use super::*;
314
315 mod metadata {
316 use super::*;
317
318 #[test]
319 fn should_be_able_to_serialize_minimal_metadata_to_json() {
320 let metadata = Metadata {
321 canonicalized_path: None,
322 file_type: FileType::Dir,
323 len: 999,
324 readonly: true,
325 accessed: None,
326 created: None,
327 modified: None,
328 unix: None,
329 windows: None,
330 };
331
332 let value = serde_json::to_value(metadata).unwrap();
333 assert_eq!(
334 value,
335 serde_json::json!({
336 "file_type": "dir",
337 "len": 999,
338 "readonly": true,
339 })
340 );
341 }
342
343 #[test]
344 fn should_be_able_to_serialize_full_metadata_to_json() {
345 let metadata = Metadata {
346 canonicalized_path: Some(PathBuf::from("test-dir")),
347 file_type: FileType::Dir,
348 len: 999,
349 readonly: true,
350 accessed: Some(u64::MAX),
351 created: Some(u64::MAX),
352 modified: Some(u64::MAX),
353 unix: Some(UnixMetadata {
354 owner_read: true,
355 owner_write: false,
356 owner_exec: false,
357 group_read: true,
358 group_write: false,
359 group_exec: false,
360 other_read: true,
361 other_write: false,
362 other_exec: false,
363 }),
364 windows: Some(WindowsMetadata {
365 archive: true,
366 compressed: false,
367 encrypted: true,
368 hidden: false,
369 integrity_stream: true,
370 normal: false,
371 not_content_indexed: true,
372 no_scrub_data: false,
373 offline: true,
374 recall_on_data_access: false,
375 recall_on_open: true,
376 reparse_point: false,
377 sparse_file: true,
378 system: false,
379 temporary: true,
380 }),
381 };
382
383 let value = serde_json::to_value(metadata).unwrap();
384 assert_eq!(
385 value,
386 serde_json::json!({
387 "canonicalized_path": "test-dir",
388 "file_type": "dir",
389 "len": 999,
390 "readonly": true,
391 "accessed": u64::MAX,
392 "created": u64::MAX,
393 "modified": u64::MAX,
394 "unix": {
395 "owner_read": true,
396 "owner_write": false,
397 "owner_exec": false,
398 "group_read": true,
399 "group_write": false,
400 "group_exec": false,
401 "other_read": true,
402 "other_write": false,
403 "other_exec": false,
404 },
405 "windows": {
406 "archive": true,
407 "compressed": false,
408 "encrypted": true,
409 "hidden": false,
410 "integrity_stream": true,
411 "normal": false,
412 "not_content_indexed": true,
413 "no_scrub_data": false,
414 "offline": true,
415 "recall_on_data_access": false,
416 "recall_on_open": true,
417 "reparse_point": false,
418 "sparse_file": true,
419 "system": false,
420 "temporary": true,
421 }
422 })
423 );
424 }
425
426 #[test]
427 fn should_be_able_to_deserialize_minimal_metadata_from_json() {
428 let value = serde_json::json!({
429 "file_type": "dir",
430 "len": 999,
431 "readonly": true,
432 });
433
434 let metadata: Metadata = serde_json::from_value(value).unwrap();
435 assert_eq!(
436 metadata,
437 Metadata {
438 canonicalized_path: None,
439 file_type: FileType::Dir,
440 len: 999,
441 readonly: true,
442 accessed: None,
443 created: None,
444 modified: None,
445 unix: None,
446 windows: None,
447 }
448 );
449 }
450
451 #[test]
452 fn should_be_able_to_deserialize_full_metadata_from_json() {
453 let value = serde_json::json!({
454 "canonicalized_path": "test-dir",
455 "file_type": "dir",
456 "len": 999,
457 "readonly": true,
458 "accessed": u64::MAX,
459 "created": u64::MAX,
460 "modified": u64::MAX,
461 "unix": {
462 "owner_read": true,
463 "owner_write": false,
464 "owner_exec": false,
465 "group_read": true,
466 "group_write": false,
467 "group_exec": false,
468 "other_read": true,
469 "other_write": false,
470 "other_exec": false,
471 },
472 "windows": {
473 "archive": true,
474 "compressed": false,
475 "encrypted": true,
476 "hidden": false,
477 "integrity_stream": true,
478 "normal": false,
479 "not_content_indexed": true,
480 "no_scrub_data": false,
481 "offline": true,
482 "recall_on_data_access": false,
483 "recall_on_open": true,
484 "reparse_point": false,
485 "sparse_file": true,
486 "system": false,
487 "temporary": true,
488 }
489 });
490
491 let metadata: Metadata = serde_json::from_value(value).unwrap();
492 assert_eq!(
493 metadata,
494 Metadata {
495 canonicalized_path: Some(PathBuf::from("test-dir")),
496 file_type: FileType::Dir,
497 len: 999,
498 readonly: true,
499 accessed: Some(u64::MAX),
500 created: Some(u64::MAX),
501 modified: Some(u64::MAX),
502 unix: Some(UnixMetadata {
503 owner_read: true,
504 owner_write: false,
505 owner_exec: false,
506 group_read: true,
507 group_write: false,
508 group_exec: false,
509 other_read: true,
510 other_write: false,
511 other_exec: false,
512 }),
513 windows: Some(WindowsMetadata {
514 archive: true,
515 compressed: false,
516 encrypted: true,
517 hidden: false,
518 integrity_stream: true,
519 normal: false,
520 not_content_indexed: true,
521 no_scrub_data: false,
522 offline: true,
523 recall_on_data_access: false,
524 recall_on_open: true,
525 reparse_point: false,
526 sparse_file: true,
527 system: false,
528 temporary: true,
529 }),
530 }
531 );
532 }
533
534 #[test]
535 fn should_be_able_to_serialize_minimal_metadata_to_msgpack() {
536 let metadata = Metadata {
537 canonicalized_path: None,
538 file_type: FileType::Dir,
539 len: 999,
540 readonly: true,
541 accessed: None,
542 created: None,
543 modified: None,
544 unix: None,
545 windows: None,
546 };
547
548 let _ = rmp_serde::encode::to_vec_named(&metadata).unwrap();
553 }
554
555 #[test]
556 fn should_be_able_to_serialize_full_metadata_to_msgpack() {
557 let metadata = Metadata {
558 canonicalized_path: Some(PathBuf::from("test-dir")),
559 file_type: FileType::Dir,
560 len: 999,
561 readonly: true,
562 accessed: Some(u64::MAX),
563 created: Some(u64::MAX),
564 modified: Some(u64::MAX),
565 unix: Some(UnixMetadata {
566 owner_read: true,
567 owner_write: false,
568 owner_exec: false,
569 group_read: true,
570 group_write: false,
571 group_exec: false,
572 other_read: true,
573 other_write: false,
574 other_exec: false,
575 }),
576 windows: Some(WindowsMetadata {
577 archive: true,
578 compressed: false,
579 encrypted: true,
580 hidden: false,
581 integrity_stream: true,
582 normal: false,
583 not_content_indexed: true,
584 no_scrub_data: false,
585 offline: true,
586 recall_on_data_access: false,
587 recall_on_open: true,
588 reparse_point: false,
589 sparse_file: true,
590 system: false,
591 temporary: true,
592 }),
593 };
594
595 let _ = rmp_serde::encode::to_vec_named(&metadata).unwrap();
600 }
601
602 #[test]
603 fn should_be_able_to_deserialize_minimal_metadata_from_msgpack() {
604 let buf = rmp_serde::encode::to_vec_named(&Metadata {
609 canonicalized_path: None,
610 file_type: FileType::Dir,
611 len: 999,
612 readonly: true,
613 accessed: None,
614 created: None,
615 modified: None,
616 unix: None,
617 windows: None,
618 })
619 .unwrap();
620
621 let metadata: Metadata = rmp_serde::decode::from_slice(&buf).unwrap();
622 assert_eq!(
623 metadata,
624 Metadata {
625 canonicalized_path: None,
626 file_type: FileType::Dir,
627 len: 999,
628 readonly: true,
629 accessed: None,
630 created: None,
631 modified: None,
632 unix: None,
633 windows: None,
634 }
635 );
636 }
637
638 #[test]
639 fn should_be_able_to_deserialize_full_metadata_from_msgpack() {
640 let buf = rmp_serde::encode::to_vec_named(&Metadata {
645 canonicalized_path: Some(PathBuf::from("test-dir")),
646 file_type: FileType::Dir,
647 len: 999,
648 readonly: true,
649 accessed: Some(u64::MAX),
650 created: Some(u64::MAX),
651 modified: Some(u64::MAX),
652 unix: Some(UnixMetadata {
653 owner_read: true,
654 owner_write: false,
655 owner_exec: false,
656 group_read: true,
657 group_write: false,
658 group_exec: false,
659 other_read: true,
660 other_write: false,
661 other_exec: false,
662 }),
663 windows: Some(WindowsMetadata {
664 archive: true,
665 compressed: false,
666 encrypted: true,
667 hidden: false,
668 integrity_stream: true,
669 normal: false,
670 not_content_indexed: true,
671 no_scrub_data: false,
672 offline: true,
673 recall_on_data_access: false,
674 recall_on_open: true,
675 reparse_point: false,
676 sparse_file: true,
677 system: false,
678 temporary: true,
679 }),
680 })
681 .unwrap();
682
683 let metadata: Metadata = rmp_serde::decode::from_slice(&buf).unwrap();
684 assert_eq!(
685 metadata,
686 Metadata {
687 canonicalized_path: Some(PathBuf::from("test-dir")),
688 file_type: FileType::Dir,
689 len: 999,
690 readonly: true,
691 accessed: Some(u64::MAX),
692 created: Some(u64::MAX),
693 modified: Some(u64::MAX),
694 unix: Some(UnixMetadata {
695 owner_read: true,
696 owner_write: false,
697 owner_exec: false,
698 group_read: true,
699 group_write: false,
700 group_exec: false,
701 other_read: true,
702 other_write: false,
703 other_exec: false,
704 }),
705 windows: Some(WindowsMetadata {
706 archive: true,
707 compressed: false,
708 encrypted: true,
709 hidden: false,
710 integrity_stream: true,
711 normal: false,
712 not_content_indexed: true,
713 no_scrub_data: false,
714 offline: true,
715 recall_on_data_access: false,
716 recall_on_open: true,
717 reparse_point: false,
718 sparse_file: true,
719 system: false,
720 temporary: true,
721 }),
722 }
723 );
724 }
725 }
726
727 mod unix_metadata {
728 use super::*;
729
730 #[test]
731 fn should_be_able_to_serialize_to_json() {
732 let metadata = UnixMetadata {
733 owner_read: true,
734 owner_write: false,
735 owner_exec: false,
736 group_read: true,
737 group_write: false,
738 group_exec: false,
739 other_read: true,
740 other_write: false,
741 other_exec: false,
742 };
743
744 let value = serde_json::to_value(metadata).unwrap();
745 assert_eq!(
746 value,
747 serde_json::json!({
748 "owner_read": true,
749 "owner_write": false,
750 "owner_exec": false,
751 "group_read": true,
752 "group_write": false,
753 "group_exec": false,
754 "other_read": true,
755 "other_write": false,
756 "other_exec": false,
757 })
758 );
759 }
760
761 #[test]
762 fn should_be_able_to_deserialize_from_json() {
763 let value = serde_json::json!({
764 "owner_read": true,
765 "owner_write": false,
766 "owner_exec": false,
767 "group_read": true,
768 "group_write": false,
769 "group_exec": false,
770 "other_read": true,
771 "other_write": false,
772 "other_exec": false,
773 });
774
775 let metadata: UnixMetadata = serde_json::from_value(value).unwrap();
776 assert_eq!(
777 metadata,
778 UnixMetadata {
779 owner_read: true,
780 owner_write: false,
781 owner_exec: false,
782 group_read: true,
783 group_write: false,
784 group_exec: false,
785 other_read: true,
786 other_write: false,
787 other_exec: false,
788 }
789 );
790 }
791
792 #[test]
793 fn should_be_able_to_serialize_to_msgpack() {
794 let metadata = UnixMetadata {
795 owner_read: true,
796 owner_write: false,
797 owner_exec: false,
798 group_read: true,
799 group_write: false,
800 group_exec: false,
801 other_read: true,
802 other_write: false,
803 other_exec: false,
804 };
805
806 let _ = rmp_serde::encode::to_vec_named(&metadata).unwrap();
811 }
812
813 #[test]
814 fn should_be_able_to_deserialize_from_msgpack() {
815 let buf = rmp_serde::encode::to_vec_named(&UnixMetadata {
820 owner_read: true,
821 owner_write: false,
822 owner_exec: false,
823 group_read: true,
824 group_write: false,
825 group_exec: false,
826 other_read: true,
827 other_write: false,
828 other_exec: false,
829 })
830 .unwrap();
831
832 let metadata: UnixMetadata = rmp_serde::decode::from_slice(&buf).unwrap();
833 assert_eq!(
834 metadata,
835 UnixMetadata {
836 owner_read: true,
837 owner_write: false,
838 owner_exec: false,
839 group_read: true,
840 group_write: false,
841 group_exec: false,
842 other_read: true,
843 other_write: false,
844 other_exec: false,
845 }
846 );
847 }
848 }
849
850 mod windows_metadata {
851 use super::*;
852
853 #[test]
854 fn should_be_able_to_serialize_to_json() {
855 let metadata = WindowsMetadata {
856 archive: true,
857 compressed: false,
858 encrypted: true,
859 hidden: false,
860 integrity_stream: true,
861 normal: false,
862 not_content_indexed: true,
863 no_scrub_data: false,
864 offline: true,
865 recall_on_data_access: false,
866 recall_on_open: true,
867 reparse_point: false,
868 sparse_file: true,
869 system: false,
870 temporary: true,
871 };
872
873 let value = serde_json::to_value(metadata).unwrap();
874 assert_eq!(
875 value,
876 serde_json::json!({
877 "archive": true,
878 "compressed": false,
879 "encrypted": true,
880 "hidden": false,
881 "integrity_stream": true,
882 "normal": false,
883 "not_content_indexed": true,
884 "no_scrub_data": false,
885 "offline": true,
886 "recall_on_data_access": false,
887 "recall_on_open": true,
888 "reparse_point": false,
889 "sparse_file": true,
890 "system": false,
891 "temporary": true,
892 })
893 );
894 }
895
896 #[test]
897 fn should_be_able_to_deserialize_from_json() {
898 let value = serde_json::json!({
899 "archive": true,
900 "compressed": false,
901 "encrypted": true,
902 "hidden": false,
903 "integrity_stream": true,
904 "normal": false,
905 "not_content_indexed": true,
906 "no_scrub_data": false,
907 "offline": true,
908 "recall_on_data_access": false,
909 "recall_on_open": true,
910 "reparse_point": false,
911 "sparse_file": true,
912 "system": false,
913 "temporary": true,
914 });
915
916 let metadata: WindowsMetadata = serde_json::from_value(value).unwrap();
917 assert_eq!(
918 metadata,
919 WindowsMetadata {
920 archive: true,
921 compressed: false,
922 encrypted: true,
923 hidden: false,
924 integrity_stream: true,
925 normal: false,
926 not_content_indexed: true,
927 no_scrub_data: false,
928 offline: true,
929 recall_on_data_access: false,
930 recall_on_open: true,
931 reparse_point: false,
932 sparse_file: true,
933 system: false,
934 temporary: true,
935 }
936 );
937 }
938
939 #[test]
940 fn should_be_able_to_serialize_to_msgpack() {
941 let metadata = WindowsMetadata {
942 archive: true,
943 compressed: false,
944 encrypted: true,
945 hidden: false,
946 integrity_stream: true,
947 normal: false,
948 not_content_indexed: true,
949 no_scrub_data: false,
950 offline: true,
951 recall_on_data_access: false,
952 recall_on_open: true,
953 reparse_point: false,
954 sparse_file: true,
955 system: false,
956 temporary: true,
957 };
958
959 let _ = rmp_serde::encode::to_vec_named(&metadata).unwrap();
964 }
965
966 #[test]
967 fn should_be_able_to_deserialize_from_msgpack() {
968 let buf = rmp_serde::encode::to_vec_named(&WindowsMetadata {
973 archive: true,
974 compressed: false,
975 encrypted: true,
976 hidden: false,
977 integrity_stream: true,
978 normal: false,
979 not_content_indexed: true,
980 no_scrub_data: false,
981 offline: true,
982 recall_on_data_access: false,
983 recall_on_open: true,
984 reparse_point: false,
985 sparse_file: true,
986 system: false,
987 temporary: true,
988 })
989 .unwrap();
990
991 let metadata: WindowsMetadata = rmp_serde::decode::from_slice(&buf).unwrap();
992 assert_eq!(
993 metadata,
994 WindowsMetadata {
995 archive: true,
996 compressed: false,
997 encrypted: true,
998 hidden: false,
999 integrity_stream: true,
1000 normal: false,
1001 not_content_indexed: true,
1002 no_scrub_data: false,
1003 offline: true,
1004 recall_on_data_access: false,
1005 recall_on_open: true,
1006 reparse_point: false,
1007 sparse_file: true,
1008 system: false,
1009 temporary: true,
1010 }
1011 );
1012 }
1013 }
1014}