typst_library/foundations/content/
packed.rs1use std::fmt::{self, Debug, Formatter};
2use std::hash::{Hash, Hasher};
3use std::marker::PhantomData;
4use std::ops::{Deref, DerefMut};
5
6use typst_syntax::Span;
7
8use crate::foundations::{Content, Label, NativeElement};
9use crate::introspection::Location;
10
11#[derive(Clone)]
13#[repr(transparent)]
14pub struct Packed<T: NativeElement>(
15 Content,
17 PhantomData<T>,
18);
19
20impl<T: NativeElement> Packed<T> {
21 pub fn new(element: T) -> Self {
23 Packed(element.pack(), PhantomData)
25 }
26
27 pub fn from_ref(content: &Content) -> Option<&Self> {
29 if content.is::<T>() {
30 return Some(unsafe { std::mem::transmute::<&Content, &Packed<T>>(content) });
34 }
35 None
36 }
37
38 pub fn from_mut(content: &mut Content) -> Option<&mut Self> {
40 if content.is::<T>() {
41 return Some(unsafe {
45 std::mem::transmute::<&mut Content, &mut Packed<T>>(content)
46 });
47 }
48 None
49 }
50
51 pub fn from_owned(content: Content) -> Result<Self, Content> {
53 if content.is::<T>() {
54 return Ok(unsafe { std::mem::transmute::<Content, Packed<T>>(content) });
58 }
59 Err(content)
60 }
61
62 pub fn pack(self) -> Content {
64 self.0
65 }
66
67 pub fn pack_ref(&self) -> &Content {
69 &self.0
70 }
71
72 pub fn pack_mut(&mut self) -> &mut Content {
74 &mut self.0
75 }
76
77 pub fn unpack(self) -> T {
79 (*self).clone()
81 }
82
83 pub fn span(&self) -> Span {
85 self.0.span()
86 }
87
88 pub fn spanned(self, span: Span) -> Self {
90 Self(self.0.spanned(span), PhantomData)
91 }
92
93 pub fn label(&self) -> Option<Label> {
95 self.0.label()
96 }
97
98 pub fn location(&self) -> Option<Location> {
100 self.0.location()
101 }
102
103 pub fn set_location(&mut self, location: Location) {
105 self.0.set_location(location);
106 }
107}
108
109impl<T: NativeElement> AsRef<T> for Packed<T> {
110 fn as_ref(&self) -> &T {
111 self
112 }
113}
114
115impl<T: NativeElement> AsMut<T> for Packed<T> {
116 fn as_mut(&mut self) -> &mut T {
117 self
118 }
119}
120
121impl<T: NativeElement> Deref for Packed<T> {
122 type Target = T;
123
124 fn deref(&self) -> &Self::Target {
125 unsafe { (self.0).0.data::<T>() }
127 }
128}
129
130impl<T: NativeElement> DerefMut for Packed<T> {
131 fn deref_mut(&mut self) -> &mut Self::Target {
132 unsafe { (self.0).0.data_mut::<T>() }
134 }
135}
136
137impl<T: NativeElement + Debug> Debug for Packed<T> {
138 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
139 self.0.fmt(f)
140 }
141}
142
143impl<T: NativeElement> PartialEq for Packed<T> {
144 fn eq(&self, other: &Self) -> bool {
145 self.0 == other.0
146 }
147}
148
149impl<T: NativeElement> Hash for Packed<T> {
150 fn hash<H: Hasher>(&self, state: &mut H) {
151 self.0.hash(state);
152 }
153}