1use core::{mem, ops::Deref};
4
5use facet_core::{
6 Def, Facet, FieldBuilder, Shape, StructKind, TypeOpsDirect, type_ops_direct, vtable_direct,
7};
8
9#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
14pub struct Span {
15 pub offset: usize,
17 pub len: usize,
19}
20
21impl Span {
22 pub const fn new(offset: usize, len: usize) -> Self {
24 Self { offset, len }
25 }
26
27 pub const fn is_unknown(&self) -> bool {
29 self.offset == 0 && self.len == 0
30 }
31
32 pub const fn end(&self) -> usize {
34 self.offset + self.len
35 }
36}
37
38unsafe impl Facet<'_> for Span {
40 const SHAPE: &'static Shape = &const {
41 static FIELDS: [facet_core::Field; 2] = [
42 FieldBuilder::new(
43 "offset",
44 facet_core::shape_of::<usize>,
45 mem::offset_of!(Span, offset),
46 )
47 .build(),
48 FieldBuilder::new(
49 "len",
50 facet_core::shape_of::<usize>,
51 mem::offset_of!(Span, len),
52 )
53 .build(),
54 ];
55
56 const VTABLE: facet_core::VTableDirect = vtable_direct!(Span => Debug, PartialEq);
57 const TYPE_OPS: TypeOpsDirect = type_ops_direct!(Span => Default, Clone);
58
59 Shape::builder_for_sized::<Span>("Span")
60 .vtable_direct(&VTABLE)
61 .type_ops_direct(&TYPE_OPS)
62 .ty(facet_core::Type::struct_builder(StructKind::Struct, &FIELDS).build())
63 .def(Def::Undefined)
64 .build()
65 };
66}
67
68#[derive(Debug)]
74pub struct Spanned<T> {
75 pub value: T,
77 pub span: Span,
79}
80
81impl<T> Spanned<T> {
82 pub const fn new(value: T, span: Span) -> Self {
84 Self { value, span }
85 }
86
87 pub const fn span(&self) -> Span {
89 self.span
90 }
91
92 pub const fn value(&self) -> &T {
94 &self.value
95 }
96
97 pub fn into_inner(self) -> T {
99 self.value
100 }
101}
102
103impl<T> Deref for Spanned<T> {
104 type Target = T;
105 fn deref(&self) -> &Self::Target {
106 &self.value
107 }
108}
109
110impl<T: Default> Default for Spanned<T> {
111 fn default() -> Self {
112 Self {
113 value: T::default(),
114 span: Span::default(),
115 }
116 }
117}
118
119impl<T: Clone> Clone for Spanned<T> {
120 fn clone(&self) -> Self {
121 Self {
122 value: self.value.clone(),
123 span: self.span,
124 }
125 }
126}
127
128impl<T: PartialEq> PartialEq for Spanned<T> {
129 fn eq(&self, other: &Self) -> bool {
130 self.value == other.value
132 }
133}
134
135impl<T: Eq> Eq for Spanned<T> {}
136
137unsafe impl<'a, T: Facet<'a>> Facet<'a> for Spanned<T> {
139 const SHAPE: &'static Shape = &const {
140 use facet_core::{TypeOpsIndirect, TypeParam, VTableIndirect};
141
142 unsafe fn drop_in_place<T>(ox: facet_core::OxPtrMut) {
143 unsafe { core::ptr::drop_in_place(ox.ptr().as_byte_ptr() as *mut Spanned<T>) };
145 }
146
147 Shape::builder_for_sized::<Spanned<T>>("Spanned")
148 .module_path("facet_reflect::spanned")
149 .vtable_indirect(&VTableIndirect::EMPTY)
150 .type_ops_indirect(
151 &const {
152 TypeOpsIndirect {
153 drop_in_place: drop_in_place::<T>,
154 default_in_place: None,
155 clone_into: None,
156 is_truthy: None,
157 }
158 },
159 )
160 .type_params(
161 &const {
162 [TypeParam {
163 name: "T",
164 shape: T::SHAPE,
165 }]
166 },
167 )
168 .ty(facet_core::Type::struct_builder(
169 StructKind::Struct,
170 &const {
171 [
172 FieldBuilder::new(
173 "value",
174 facet_core::shape_of::<T>,
175 mem::offset_of!(Spanned<T>, value),
176 )
177 .build(),
178 FieldBuilder::new(
179 "span",
180 facet_core::shape_of::<Span>,
181 mem::offset_of!(Spanned<T>, span),
182 )
183 .metadata("span")
186 .build(),
187 ]
188 },
189 )
190 .build())
191 .def(Def::Undefined)
192 .type_name(|_shape, f, opts| {
193 write!(f, "Spanned")?;
194 if let Some(opts) = opts.for_children() {
195 write!(f, "<")?;
196 if let Some(type_name_fn) = T::SHAPE.type_name {
197 type_name_fn(T::SHAPE, f, opts)?;
198 } else {
199 write!(f, "{}", T::SHAPE.type_identifier)?;
200 }
201 write!(f, ">")?;
202 } else {
203 write!(f, "<…>")?;
204 }
205 Ok(())
206 })
207 .build()
208 };
209}
210
211pub fn is_spanned_shape(shape: &Shape) -> bool {
220 use facet_core::{Type, UserType};
221
222 if let Type::User(UserType::Struct(struct_def)) = &shape.ty {
223 let has_span_metadata = struct_def
224 .fields
225 .iter()
226 .any(|f| f.metadata_kind() == Some("span"));
227 let has_value_field = struct_def.fields.iter().any(|f| !f.is_metadata());
228 return has_span_metadata && has_value_field;
229 }
230 false
231}
232
233pub fn find_span_metadata_field(shape: &Shape) -> Option<&'static facet_core::Field> {
237 use facet_core::{Type, UserType};
238
239 if let Type::User(UserType::Struct(struct_def)) = &shape.ty {
240 return struct_def
241 .fields
242 .iter()
243 .find(|f| f.metadata_kind() == Some("span"));
244 }
245 None
246}
247
248pub fn get_spanned_inner_shape(shape: &Shape) -> Option<&'static Shape> {
259 use facet_core::{Type, UserType};
260
261 if !is_spanned_shape(shape) {
262 return None;
263 }
264
265 if let Type::User(UserType::Struct(struct_def)) = &shape.ty {
266 struct_def
268 .fields
269 .iter()
270 .find(|f| !f.is_metadata())
271 .map(|f| f.shape.get())
272 } else {
273 None
274 }
275}