Skip to main content

oxidize_pdf/pdf_objects/
mod.rs

1//! Unified PDF Object Types
2//!
3//! This module provides the canonical PDF object types used throughout oxidize-pdf.
4//! These types unify the previously separate parser and writer type systems.
5//!
6//! # Migration from v1.5.0
7//!
8//! - `parser::objects::PdfObject` → `pdf_objects::Object`
9//! - `parser::objects::PdfDictionary` → `pdf_objects::Dictionary`
10//! - `parser::objects::PdfName` → `pdf_objects::Name`
11//! - `parser::objects::PdfArray` → `pdf_objects::Array`
12//! - `parser::objects::PdfString` → `pdf_objects::BinaryString`
13//! - `objects::primitive::Object` → `pdf_objects::Object`
14//! - `objects::primitive::ObjectId` → `pdf_objects::ObjectId`
15//! - `objects::dictionary::Dictionary` → `pdf_objects::Dictionary`
16//!
17//! Type aliases with deprecation warnings are provided for backward compatibility.
18
19use std::collections::HashMap;
20use std::fmt;
21
22/// PDF Name - Unique atomic symbol in PDF
23///
24/// Names are used as keys in dictionaries and to identify PDF constructs.
25/// Written with leading slash (/) in PDF syntax but stored without it.
26#[derive(Debug, Clone, PartialEq, Eq, Hash)]
27pub struct Name(String);
28
29impl Name {
30    pub fn new(name: impl Into<String>) -> Self {
31        Self(name.into())
32    }
33
34    pub fn as_str(&self) -> &str {
35        &self.0
36    }
37
38    pub fn into_string(self) -> String {
39        self.0
40    }
41}
42
43impl From<&str> for Name {
44    fn from(s: &str) -> Self {
45        Self(s.to_string())
46    }
47}
48
49impl From<String> for Name {
50    fn from(s: String) -> Self {
51        Self(s)
52    }
53}
54
55impl AsRef<str> for Name {
56    fn as_ref(&self) -> &str {
57        &self.0
58    }
59}
60
61impl fmt::Display for Name {
62    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63        write!(f, "/{}", self.0)
64    }
65}
66
67/// Binary String - Arbitrary binary data in PDF
68///
69/// PDF strings can contain binary data or text in various encodings.
70/// This type supports both, unlike Rust's UTF-8 String.
71#[derive(Debug, Clone, PartialEq, Eq, Hash)]
72pub struct BinaryString(Vec<u8>);
73
74impl BinaryString {
75    pub fn new(data: Vec<u8>) -> Self {
76        Self(data)
77    }
78
79    pub fn from_str(s: &str) -> Self {
80        Self(s.as_bytes().to_vec())
81    }
82
83    pub fn as_bytes(&self) -> &[u8] {
84        &self.0
85    }
86
87    pub fn into_bytes(self) -> Vec<u8> {
88        self.0
89    }
90
91    pub fn to_string_lossy(&self) -> String {
92        String::from_utf8_lossy(&self.0).to_string()
93    }
94
95    pub fn try_to_string(&self) -> Option<String> {
96        String::from_utf8(self.0.clone()).ok()
97    }
98}
99
100impl From<Vec<u8>> for BinaryString {
101    fn from(data: Vec<u8>) -> Self {
102        Self(data)
103    }
104}
105
106impl From<&[u8]> for BinaryString {
107    fn from(data: &[u8]) -> Self {
108        Self(data.to_vec())
109    }
110}
111
112impl From<String> for BinaryString {
113    fn from(s: String) -> Self {
114        Self(s.into_bytes())
115    }
116}
117
118impl From<&str> for BinaryString {
119    fn from(s: &str) -> Self {
120        Self(s.as_bytes().to_vec())
121    }
122}
123
124/// Object ID - Reference to indirect PDF object
125#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
126pub struct ObjectId {
127    number: u32,
128    generation: u16,
129}
130
131impl ObjectId {
132    pub fn new(number: u32, generation: u16) -> Self {
133        Self { number, generation }
134    }
135
136    pub fn number(&self) -> u32 {
137        self.number
138    }
139
140    pub fn generation(&self) -> u16 {
141        self.generation
142    }
143}
144
145impl From<(u32, u16)> for ObjectId {
146    fn from((number, generation): (u32, u16)) -> Self {
147        Self::new(number, generation)
148    }
149}
150
151impl fmt::Display for ObjectId {
152    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
153        write!(f, "{} {} R", self.number, self.generation)
154    }
155}
156
157/// PDF Array - Ordered collection of objects
158#[derive(Debug, Clone, PartialEq)]
159pub struct Array(Vec<Object>);
160
161impl Array {
162    pub fn new() -> Self {
163        Self(Vec::new())
164    }
165
166    pub fn with_capacity(capacity: usize) -> Self {
167        Self(Vec::with_capacity(capacity))
168    }
169
170    pub fn push(&mut self, obj: impl Into<Object>) {
171        self.0.push(obj.into());
172    }
173
174    pub fn get(&self, index: usize) -> Option<&Object> {
175        self.0.get(index)
176    }
177
178    pub fn len(&self) -> usize {
179        self.0.len()
180    }
181
182    pub fn is_empty(&self) -> bool {
183        self.0.is_empty()
184    }
185
186    pub fn iter(&self) -> impl Iterator<Item = &Object> {
187        self.0.iter()
188    }
189
190    pub fn as_slice(&self) -> &[Object] {
191        &self.0
192    }
193
194    pub fn into_vec(self) -> Vec<Object> {
195        self.0
196    }
197}
198
199impl Default for Array {
200    fn default() -> Self {
201        Self::new()
202    }
203}
204
205impl From<Vec<Object>> for Array {
206    fn from(vec: Vec<Object>) -> Self {
207        Self(vec)
208    }
209}
210
211impl FromIterator<Object> for Array {
212    fn from_iter<T: IntoIterator<Item = Object>>(iter: T) -> Self {
213        Self(iter.into_iter().collect())
214    }
215}
216
217/// PDF Dictionary - Key-value mapping with Name keys
218#[derive(Debug, Clone, PartialEq)]
219pub struct Dictionary {
220    entries: HashMap<Name, Object>,
221}
222
223impl Dictionary {
224    pub fn new() -> Self {
225        Self {
226            entries: HashMap::new(),
227        }
228    }
229
230    pub fn with_capacity(capacity: usize) -> Self {
231        Self {
232            entries: HashMap::with_capacity(capacity),
233        }
234    }
235
236    pub fn set(&mut self, key: impl Into<Name>, value: impl Into<Object>) {
237        self.entries.insert(key.into(), value.into());
238    }
239
240    pub fn get(&self, key: impl AsRef<str>) -> Option<&Object> {
241        self.entries.get(&Name::new(key.as_ref()))
242    }
243
244    pub fn get_mut(&mut self, key: impl AsRef<str>) -> Option<&mut Object> {
245        self.entries.get_mut(&Name::new(key.as_ref()))
246    }
247
248    pub fn remove(&mut self, key: impl AsRef<str>) -> Option<Object> {
249        self.entries.remove(&Name::new(key.as_ref()))
250    }
251
252    pub fn contains_key(&self, key: impl AsRef<str>) -> bool {
253        self.entries.contains_key(&Name::new(key.as_ref()))
254    }
255
256    pub fn len(&self) -> usize {
257        self.entries.len()
258    }
259
260    pub fn is_empty(&self) -> bool {
261        self.entries.is_empty()
262    }
263
264    pub fn clear(&mut self) {
265        self.entries.clear();
266    }
267
268    pub fn keys(&self) -> impl Iterator<Item = &Name> {
269        self.entries.keys()
270    }
271
272    pub fn values(&self) -> impl Iterator<Item = &Object> {
273        self.entries.values()
274    }
275
276    pub fn iter(&self) -> impl Iterator<Item = (&Name, &Object)> {
277        self.entries.iter()
278    }
279
280    pub fn get_dict(&self, key: impl AsRef<str>) -> Option<&Dictionary> {
281        self.get(key).and_then(|obj| {
282            if let Object::Dictionary(dict) = obj {
283                Some(dict)
284            } else {
285                None
286            }
287        })
288    }
289
290    pub fn get_type(&self) -> Option<&str> {
291        self.get("Type").and_then(|obj| {
292            if let Object::Name(name) = obj {
293                Some(name.as_str())
294            } else {
295                None
296            }
297        })
298    }
299}
300
301impl Default for Dictionary {
302    fn default() -> Self {
303        Self::new()
304    }
305}
306
307/// PDF Stream - Dictionary with binary data
308#[derive(Debug, Clone, PartialEq)]
309pub struct Stream {
310    pub dict: Dictionary,
311    pub data: Vec<u8>,
312}
313
314impl Stream {
315    pub fn new(dict: Dictionary, data: Vec<u8>) -> Self {
316        Self { dict, data }
317    }
318}
319
320/// PDF Object - The fundamental PDF data type
321#[derive(Debug, Clone, PartialEq)]
322pub enum Object {
323    /// Null object - represents undefined/absent values
324    Null,
325    /// Boolean value
326    Boolean(bool),
327    /// Integer number
328    Integer(i64),
329    /// Real (floating-point) number
330    Real(f64),
331    /// String data (can be binary or text)
332    String(BinaryString),
333    /// Name object - unique identifier
334    Name(Name),
335    /// Array - ordered collection
336    Array(Array),
337    /// Dictionary - key-value pairs
338    Dictionary(Dictionary),
339    /// Stream - dictionary with binary data
340    Stream(Stream),
341    /// Indirect object reference
342    Reference(ObjectId),
343}
344
345impl Object {
346    pub fn is_null(&self) -> bool {
347        matches!(self, Object::Null)
348    }
349
350    pub fn as_bool(&self) -> Option<bool> {
351        match self {
352            Object::Boolean(b) => Some(*b),
353            _ => None,
354        }
355    }
356
357    pub fn as_integer(&self) -> Option<i64> {
358        match self {
359            Object::Integer(i) => Some(*i),
360            _ => None,
361        }
362    }
363
364    pub fn as_real(&self) -> Option<f64> {
365        match self {
366            Object::Real(f) => Some(*f),
367            Object::Integer(i) => Some(*i as f64),
368            _ => None,
369        }
370    }
371
372    pub fn as_string(&self) -> Option<&BinaryString> {
373        match self {
374            Object::String(s) => Some(s),
375            _ => None,
376        }
377    }
378
379    pub fn as_name(&self) -> Option<&Name> {
380        match self {
381            Object::Name(n) => Some(n),
382            _ => None,
383        }
384    }
385
386    pub fn as_array(&self) -> Option<&Array> {
387        match self {
388            Object::Array(arr) => Some(arr),
389            _ => None,
390        }
391    }
392
393    pub fn as_dict(&self) -> Option<&Dictionary> {
394        match self {
395            Object::Dictionary(dict) => Some(dict),
396            _ => None,
397        }
398    }
399
400    pub fn as_stream(&self) -> Option<&Stream> {
401        match self {
402            Object::Stream(stream) => Some(stream),
403            _ => None,
404        }
405    }
406
407    pub fn as_reference(&self) -> Option<ObjectId> {
408        match self {
409            Object::Reference(id) => Some(*id),
410            _ => None,
411        }
412    }
413}
414
415// Conversions from primitive types
416impl From<bool> for Object {
417    fn from(b: bool) -> Self {
418        Object::Boolean(b)
419    }
420}
421
422impl From<i32> for Object {
423    fn from(i: i32) -> Self {
424        Object::Integer(i as i64)
425    }
426}
427
428impl From<i64> for Object {
429    fn from(i: i64) -> Self {
430        Object::Integer(i)
431    }
432}
433
434impl From<f32> for Object {
435    fn from(f: f32) -> Self {
436        Object::Real(f as f64)
437    }
438}
439
440impl From<f64> for Object {
441    fn from(f: f64) -> Self {
442        Object::Real(f)
443    }
444}
445
446impl From<String> for Object {
447    fn from(s: String) -> Self {
448        Object::String(BinaryString::from(s))
449    }
450}
451
452impl From<&str> for Object {
453    fn from(s: &str) -> Self {
454        Object::String(BinaryString::from(s))
455    }
456}
457
458impl From<BinaryString> for Object {
459    fn from(s: BinaryString) -> Self {
460        Object::String(s)
461    }
462}
463
464impl From<Name> for Object {
465    fn from(n: Name) -> Self {
466        Object::Name(n)
467    }
468}
469
470impl From<Array> for Object {
471    fn from(a: Array) -> Self {
472        Object::Array(a)
473    }
474}
475
476impl From<Vec<Object>> for Object {
477    fn from(v: Vec<Object>) -> Self {
478        Object::Array(Array::from(v))
479    }
480}
481
482impl From<Dictionary> for Object {
483    fn from(d: Dictionary) -> Self {
484        Object::Dictionary(d)
485    }
486}
487
488impl From<Stream> for Object {
489    fn from(s: Stream) -> Self {
490        Object::Stream(s)
491    }
492}
493
494impl From<ObjectId> for Object {
495    fn from(id: ObjectId) -> Self {
496        Object::Reference(id)
497    }
498}
499
500impl From<(u32, u16)> for Object {
501    fn from((number, generation): (u32, u16)) -> Self {
502        Object::Reference(ObjectId::new(number, generation))
503    }
504}
505
506#[cfg(test)]
507mod tests {
508    use super::*;
509
510    // =============================================================================
511    // Name tests
512    // =============================================================================
513
514    #[test]
515    fn test_name() {
516        let name = Name::new("Type");
517        assert_eq!(name.as_str(), "Type");
518        assert_eq!(format!("{}", name), "/Type");
519    }
520
521    #[test]
522    fn test_name_into_string() {
523        let name = Name::new("Type");
524        let s = name.into_string();
525        assert_eq!(s, "Type");
526    }
527
528    #[test]
529    fn test_name_from_string() {
530        let name: Name = String::from("Test").into();
531        assert_eq!(name.as_str(), "Test");
532    }
533
534    #[test]
535    fn test_name_as_ref() {
536        let name = Name::new("Type");
537        let s: &str = name.as_ref();
538        assert_eq!(s, "Type");
539    }
540
541    #[test]
542    fn test_name_from_str() {
543        let name: Name = "Type".into();
544        assert_eq!(name.as_str(), "Type");
545    }
546
547    // =============================================================================
548    // BinaryString tests
549    // =============================================================================
550
551    #[test]
552    fn test_binary_string() {
553        let s1 = BinaryString::from("Hello");
554        assert_eq!(s1.to_string_lossy(), "Hello");
555
556        let s2 = BinaryString::new(vec![0xFF, 0xFE, 0x48, 0x69]);
557        assert!(s2.try_to_string().is_none());
558        assert!(!s2.to_string_lossy().is_empty());
559    }
560
561    #[test]
562    fn test_binary_string_from_str_method() {
563        let s = BinaryString::from_str("Hello");
564        assert_eq!(s.as_bytes(), b"Hello");
565    }
566
567    #[test]
568    fn test_binary_string_into_bytes() {
569        let s = BinaryString::new(vec![1, 2, 3]);
570        let bytes = s.into_bytes();
571        assert_eq!(bytes, vec![1, 2, 3]);
572    }
573
574    #[test]
575    fn test_binary_string_from_vec() {
576        let s: BinaryString = vec![65, 66, 67].into();
577        assert_eq!(s.as_bytes(), &[65, 66, 67]);
578    }
579
580    #[test]
581    fn test_binary_string_from_slice() {
582        let data: &[u8] = &[1, 2, 3];
583        let s: BinaryString = data.into();
584        assert_eq!(s.as_bytes(), &[1, 2, 3]);
585    }
586
587    #[test]
588    fn test_binary_string_from_string() {
589        let s: BinaryString = String::from("Test").into();
590        assert_eq!(s.as_bytes(), b"Test");
591    }
592
593    #[test]
594    fn test_binary_string_try_to_string_valid_utf8() {
595        let s = BinaryString::from_str("Valid UTF-8");
596        assert_eq!(s.try_to_string(), Some("Valid UTF-8".to_string()));
597    }
598
599    // =============================================================================
600    // ObjectId tests
601    // =============================================================================
602
603    #[test]
604    fn test_object_id() {
605        let id = ObjectId::new(10, 0);
606        assert_eq!(id.number(), 10);
607        assert_eq!(id.generation(), 0);
608        assert_eq!(format!("{}", id), "10 0 R");
609    }
610
611    #[test]
612    fn test_object_id_from_tuple() {
613        let id: ObjectId = (42u32, 1u16).into();
614        assert_eq!(id.number(), 42);
615        assert_eq!(id.generation(), 1);
616    }
617
618    // =============================================================================
619    // Array tests
620    // =============================================================================
621
622    #[test]
623    fn test_array() {
624        let mut arr = Array::new();
625        arr.push(Object::Integer(1));
626        arr.push(Object::Integer(2));
627        arr.push(Object::Integer(3));
628
629        assert_eq!(arr.len(), 3);
630        assert_eq!(arr.get(1), Some(&Object::Integer(2)));
631    }
632
633    #[test]
634    fn test_array_with_capacity() {
635        let arr = Array::with_capacity(100);
636        assert!(arr.is_empty());
637        assert_eq!(arr.len(), 0);
638    }
639
640    #[test]
641    fn test_array_is_empty() {
642        let arr = Array::new();
643        assert!(arr.is_empty());
644    }
645
646    #[test]
647    fn test_array_iter() {
648        let mut arr = Array::new();
649        arr.push(Object::Integer(1));
650        arr.push(Object::Integer(2));
651
652        let sum: i64 = arr.iter().filter_map(|o| o.as_integer()).sum();
653        assert_eq!(sum, 3);
654    }
655
656    #[test]
657    fn test_array_as_slice() {
658        let mut arr = Array::new();
659        arr.push(Object::Integer(1));
660
661        let slice = arr.as_slice();
662        assert_eq!(slice.len(), 1);
663    }
664
665    #[test]
666    fn test_array_into_vec() {
667        let mut arr = Array::new();
668        arr.push(Object::Integer(42));
669
670        let vec = arr.into_vec();
671        assert_eq!(vec.len(), 1);
672    }
673
674    #[test]
675    fn test_array_default() {
676        let arr: Array = Default::default();
677        assert!(arr.is_empty());
678    }
679
680    #[test]
681    fn test_array_from_vec() {
682        let vec = vec![Object::Integer(1), Object::Integer(2)];
683        let arr = Array::from(vec);
684        assert_eq!(arr.len(), 2);
685    }
686
687    #[test]
688    fn test_array_from_iterator() {
689        let arr: Array = vec![Object::Integer(1), Object::Integer(2)]
690            .into_iter()
691            .collect();
692        assert_eq!(arr.len(), 2);
693    }
694
695    #[test]
696    fn test_array_get_out_of_bounds() {
697        let arr = Array::new();
698        assert!(arr.get(0).is_none());
699    }
700
701    // =============================================================================
702    // Dictionary tests
703    // =============================================================================
704
705    #[test]
706    fn test_dictionary() {
707        let mut dict = Dictionary::new();
708        dict.set("Type", Name::new("Page"));
709        dict.set("Count", 5);
710
711        assert_eq!(dict.get_type(), Some("Page"));
712        assert_eq!(dict.get("Count"), Some(&Object::Integer(5)));
713    }
714
715    #[test]
716    fn test_dictionary_with_capacity() {
717        let dict = Dictionary::with_capacity(100);
718        assert!(dict.is_empty());
719    }
720
721    #[test]
722    fn test_dictionary_get_mut() {
723        let mut dict = Dictionary::new();
724        dict.set("Count", 5);
725
726        if let Some(obj) = dict.get_mut("Count") {
727            *obj = Object::Integer(10);
728        }
729        assert_eq!(dict.get("Count"), Some(&Object::Integer(10)));
730    }
731
732    #[test]
733    fn test_dictionary_remove() {
734        let mut dict = Dictionary::new();
735        dict.set("Key", 1);
736
737        let removed = dict.remove("Key");
738        assert_eq!(removed, Some(Object::Integer(1)));
739        assert!(dict.is_empty());
740    }
741
742    #[test]
743    fn test_dictionary_remove_nonexistent() {
744        let mut dict = Dictionary::new();
745        assert!(dict.remove("NonExistent").is_none());
746    }
747
748    #[test]
749    fn test_dictionary_contains_key() {
750        let mut dict = Dictionary::new();
751        dict.set("Key", 1);
752
753        assert!(dict.contains_key("Key"));
754        assert!(!dict.contains_key("Other"));
755    }
756
757    #[test]
758    fn test_dictionary_clear() {
759        let mut dict = Dictionary::new();
760        dict.set("A", 1);
761        dict.set("B", 2);
762
763        dict.clear();
764        assert!(dict.is_empty());
765    }
766
767    #[test]
768    fn test_dictionary_keys() {
769        let mut dict = Dictionary::new();
770        dict.set("A", 1);
771        dict.set("B", 2);
772
773        let keys: Vec<&str> = dict.keys().map(|n| n.as_str()).collect();
774        assert!(keys.contains(&"A"));
775        assert!(keys.contains(&"B"));
776    }
777
778    #[test]
779    fn test_dictionary_values() {
780        let mut dict = Dictionary::new();
781        dict.set("A", 1);
782        dict.set("B", 2);
783
784        let count = dict.values().count();
785        assert_eq!(count, 2);
786    }
787
788    #[test]
789    fn test_dictionary_iter() {
790        let mut dict = Dictionary::new();
791        dict.set("A", 1);
792
793        for (name, _obj) in dict.iter() {
794            assert_eq!(name.as_str(), "A");
795        }
796    }
797
798    #[test]
799    fn test_dictionary_get_dict() {
800        let mut inner = Dictionary::new();
801        inner.set("Inner", 1);
802
803        let mut outer = Dictionary::new();
804        outer.set("Nested", Object::Dictionary(inner));
805
806        let nested = outer.get_dict("Nested");
807        assert!(nested.is_some());
808        assert_eq!(nested.unwrap().len(), 1);
809    }
810
811    #[test]
812    fn test_dictionary_get_dict_not_dict() {
813        let mut dict = Dictionary::new();
814        dict.set("Key", 42);
815
816        assert!(dict.get_dict("Key").is_none());
817    }
818
819    #[test]
820    fn test_dictionary_get_type_not_name() {
821        let mut dict = Dictionary::new();
822        dict.set("Type", 42);
823
824        assert!(dict.get_type().is_none());
825    }
826
827    #[test]
828    fn test_dictionary_default() {
829        let dict: Dictionary = Default::default();
830        assert!(dict.is_empty());
831    }
832
833    // =============================================================================
834    // Stream tests
835    // =============================================================================
836
837    #[test]
838    fn test_stream_new() {
839        let dict = Dictionary::new();
840        let data = vec![1, 2, 3, 4, 5];
841        let stream = Stream::new(dict, data.clone());
842
843        assert!(stream.dict.is_empty());
844        assert_eq!(stream.data, data);
845    }
846
847    // =============================================================================
848    // Object tests
849    // =============================================================================
850
851    #[test]
852    fn test_object_conversions() {
853        let obj1: Object = true.into();
854        assert_eq!(obj1, Object::Boolean(true));
855
856        let obj2: Object = 42.into();
857        assert_eq!(obj2, Object::Integer(42));
858
859        let obj3: Object = "test".into();
860        if let Object::String(s) = obj3 {
861            assert_eq!(s.to_string_lossy(), "test");
862        } else {
863            panic!("Expected String");
864        }
865    }
866
867    #[test]
868    fn test_object_is_null() {
869        assert!(Object::Null.is_null());
870        assert!(!Object::Integer(0).is_null());
871    }
872
873    #[test]
874    fn test_object_as_bool() {
875        assert_eq!(Object::Boolean(true).as_bool(), Some(true));
876        assert_eq!(Object::Boolean(false).as_bool(), Some(false));
877        assert_eq!(Object::Integer(1).as_bool(), None);
878    }
879
880    #[test]
881    fn test_object_as_integer() {
882        assert_eq!(Object::Integer(42).as_integer(), Some(42));
883        assert_eq!(Object::Real(3.14).as_integer(), None);
884    }
885
886    #[test]
887    fn test_object_as_real() {
888        assert_eq!(Object::Real(3.14).as_real(), Some(3.14));
889        // Integer can be converted to real
890        assert_eq!(Object::Integer(42).as_real(), Some(42.0));
891        assert_eq!(Object::Boolean(true).as_real(), None);
892    }
893
894    #[test]
895    fn test_object_as_string() {
896        let s = BinaryString::from("test");
897        let obj = Object::String(s.clone());
898        assert!(obj.as_string().is_some());
899        assert_eq!(Object::Integer(1).as_string(), None);
900    }
901
902    #[test]
903    fn test_object_as_name() {
904        let name = Name::new("Type");
905        let obj = Object::Name(name);
906        assert!(obj.as_name().is_some());
907        assert_eq!(Object::Integer(1).as_name(), None);
908    }
909
910    #[test]
911    fn test_object_as_array() {
912        let arr = Array::new();
913        let obj = Object::Array(arr);
914        assert!(obj.as_array().is_some());
915        assert_eq!(Object::Integer(1).as_array(), None);
916    }
917
918    #[test]
919    fn test_object_as_dict() {
920        let dict = Dictionary::new();
921        let obj = Object::Dictionary(dict);
922        assert!(obj.as_dict().is_some());
923        assert_eq!(Object::Integer(1).as_dict(), None);
924    }
925
926    #[test]
927    fn test_object_as_stream() {
928        let stream = Stream::new(Dictionary::new(), vec![]);
929        let obj = Object::Stream(stream);
930        assert!(obj.as_stream().is_some());
931        assert_eq!(Object::Integer(1).as_stream(), None);
932    }
933
934    #[test]
935    fn test_object_as_reference() {
936        let id = ObjectId::new(1, 0);
937        let obj = Object::Reference(id);
938        assert_eq!(obj.as_reference(), Some(id));
939        assert_eq!(Object::Integer(1).as_reference(), None);
940    }
941
942    #[test]
943    fn test_object_from_i64() {
944        let obj: Object = 42i64.into();
945        assert_eq!(obj.as_integer(), Some(42));
946    }
947
948    #[test]
949    fn test_object_from_f32() {
950        let obj: Object = 3.14f32.into();
951        assert!(obj.as_real().is_some());
952    }
953
954    #[test]
955    fn test_object_from_f64() {
956        let obj: Object = 3.14f64.into();
957        assert_eq!(obj.as_real(), Some(3.14));
958    }
959
960    #[test]
961    fn test_object_from_string() {
962        let obj: Object = String::from("test").into();
963        assert!(obj.as_string().is_some());
964    }
965
966    #[test]
967    fn test_object_from_binary_string() {
968        let bs = BinaryString::from("test");
969        let obj: Object = bs.into();
970        assert!(obj.as_string().is_some());
971    }
972
973    #[test]
974    fn test_object_from_name() {
975        let name = Name::new("Type");
976        let obj: Object = name.into();
977        assert!(obj.as_name().is_some());
978    }
979
980    #[test]
981    fn test_object_from_array() {
982        let arr = Array::new();
983        let obj: Object = arr.into();
984        assert!(obj.as_array().is_some());
985    }
986
987    #[test]
988    fn test_object_from_vec() {
989        let vec = vec![Object::Integer(1)];
990        let obj: Object = vec.into();
991        assert!(obj.as_array().is_some());
992    }
993
994    #[test]
995    fn test_object_from_dictionary() {
996        let dict = Dictionary::new();
997        let obj: Object = dict.into();
998        assert!(obj.as_dict().is_some());
999    }
1000
1001    #[test]
1002    fn test_object_from_stream() {
1003        let stream = Stream::new(Dictionary::new(), vec![]);
1004        let obj: Object = stream.into();
1005        assert!(obj.as_stream().is_some());
1006    }
1007
1008    #[test]
1009    fn test_object_from_object_id() {
1010        let id = ObjectId::new(1, 0);
1011        let obj: Object = id.into();
1012        assert!(obj.as_reference().is_some());
1013    }
1014
1015    #[test]
1016    fn test_object_from_tuple() {
1017        let obj: Object = (1u32, 0u16).into();
1018        assert!(obj.as_reference().is_some());
1019    }
1020}