1extern crate alloc;
12
13use alloc::borrow::Cow;
14use alloc::vec::Vec;
15
16use facet_core::{Def, StructKind, Type, UserType};
17use facet_reflect::{HasFields, Peek};
18
19use crate::error::SerializeError;
20
21pub trait Writer {
71 fn write_byte(&mut self, byte: u8) -> Result<(), SerializeError>;
73
74 fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), SerializeError>;
76}
77
78impl Writer for Vec<u8> {
79 fn write_byte(&mut self, byte: u8) -> Result<(), SerializeError> {
80 self.push(byte);
81 Ok(())
82 }
83
84 fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), SerializeError> {
85 self.extend_from_slice(bytes);
86 Ok(())
87 }
88}
89
90pub fn to_vec<T>(value: &T) -> Result<Vec<u8>, SerializeError>
107where
108 T: facet_core::Facet<'static>,
109{
110 let mut buffer = Vec::new();
111 to_writer_fallible(value, &mut buffer)?;
112 Ok(buffer)
113}
114
115pub fn to_writer_fallible<T, W>(value: &T, writer: &mut W) -> Result<(), SerializeError>
154where
155 T: facet_core::Facet<'static>,
156 W: Writer,
157{
158 let peek = Peek::new(value);
159 serialize_value(peek, writer)
160}
161
162fn serialize_value<W: Writer>(peek: Peek<'_, '_>, writer: &mut W) -> Result<(), SerializeError> {
164 match (peek.shape().def, peek.shape().ty) {
165 (Def::Scalar, _) => {
166 let peek = peek.innermost_peek();
167 serialize_scalar(peek, writer)
168 }
169 (Def::List(ld), _) => {
170 if ld.t().is_type::<u8>() && peek.shape().is_type::<Vec<u8>>() {
172 let bytes = peek.get::<Vec<u8>>().map_err(|e| {
173 SerializeError::Custom(alloc::format!("Failed to get Vec<u8>: {}", e))
174 })?;
175 write_varint(bytes.len() as u64, writer)?;
176 return writer.write_bytes(bytes);
177 }
178 #[cfg(feature = "bytes")]
180 if ld.t().is_type::<u8>() && peek.shape().type_identifier == "Bytes" {
181 use bytes::Bytes;
182 let bytes = peek.get::<Bytes>().map_err(|e| {
183 SerializeError::Custom(alloc::format!("Failed to get Bytes: {}", e))
184 })?;
185 write_varint(bytes.len() as u64, writer)?;
186 return writer.write_bytes(bytes);
187 }
188 #[cfg(feature = "bytes")]
190 if ld.t().is_type::<u8>() && peek.shape().type_identifier == "BytesMut" {
191 use bytes::BytesMut;
192 let bytes_mut = peek.get::<BytesMut>().map_err(|e| {
193 SerializeError::Custom(alloc::format!("Failed to get BytesMut: {}", e))
194 })?;
195 write_varint(bytes_mut.len() as u64, writer)?;
196 return writer.write_bytes(bytes_mut);
197 }
198 let list = peek.into_list_like().map_err(|e| {
200 SerializeError::Custom(alloc::format!("Failed to convert to list: {}", e))
201 })?;
202 let items: Vec<_> = list.iter().collect();
203 write_varint(items.len() as u64, writer)?;
204 for item in items {
205 serialize_value(item, writer)?;
206 }
207 Ok(())
208 }
209 (Def::Array(ad), _) => {
210 if ad.t().is_type::<u8>() {
211 let list = peek.into_list_like().map_err(|e| {
213 SerializeError::Custom(alloc::format!("Failed to convert to list: {}", e))
214 })?;
215 let bytes: Vec<u8> = list
216 .iter()
217 .map(|p| {
218 *p.get::<u8>()
219 .expect("Failed to get u8 from byte array element")
220 })
221 .collect();
222 writer.write_bytes(&bytes)
223 } else {
224 let list = peek.into_list_like().map_err(|e| {
226 SerializeError::Custom(alloc::format!("Failed to convert to list: {}", e))
227 })?;
228 for item in list.iter() {
229 serialize_value(item, writer)?;
230 }
231 Ok(())
232 }
233 }
234 (Def::Slice(sd), _) => {
235 if sd.t().is_type::<u8>() {
236 let bytes = peek.get::<[u8]>().map_err(|e| {
237 SerializeError::Custom(alloc::format!("Failed to get [u8]: {}", e))
238 })?;
239 write_varint(bytes.len() as u64, writer)?;
240 writer.write_bytes(bytes)
241 } else {
242 let list = peek.into_list_like().map_err(|e| {
243 SerializeError::Custom(alloc::format!("Failed to convert to list: {}", e))
244 })?;
245 let items: Vec<_> = list.iter().collect();
246 write_varint(items.len() as u64, writer)?;
247 for item in items {
248 serialize_value(item, writer)?;
249 }
250 Ok(())
251 }
252 }
253 (Def::Map(_), _) => {
254 let map = peek.into_map().map_err(|e| {
255 SerializeError::Custom(alloc::format!("Failed to convert to map: {}", e))
256 })?;
257 let entries: Vec<_> = map.iter().collect();
258 write_varint(entries.len() as u64, writer)?;
259 for (key, value) in entries {
260 serialize_value(key, writer)?;
261 serialize_value(value, writer)?;
262 }
263 Ok(())
264 }
265 (Def::Set(_), _) => {
266 let set = peek.into_set().map_err(|e| {
267 SerializeError::Custom(alloc::format!("Failed to convert to set: {}", e))
268 })?;
269 let items: Vec<_> = set.iter().collect();
270 write_varint(items.len() as u64, writer)?;
271 for item in items {
272 serialize_value(item, writer)?;
273 }
274 Ok(())
275 }
276 (Def::Option(_), _) => {
277 let opt = peek.into_option().map_err(|e| {
278 SerializeError::Custom(alloc::format!("Failed to convert to option: {}", e))
279 })?;
280 if let Some(inner) = opt.value() {
281 writer.write_byte(1)?; serialize_value(inner, writer)
283 } else {
284 writer.write_byte(0) }
286 }
287 (Def::Result(_), _) => {
288 let res = peek.into_result().map_err(|e| {
289 SerializeError::Custom(alloc::format!("Failed to convert to result: {}", e))
290 })?;
291 if let Some(ok_value) = res.ok() {
292 write_varint(0, writer)?;
294 serialize_value(ok_value, writer)
295 } else if let Some(err_value) = res.err() {
296 write_varint(1, writer)?;
298 serialize_value(err_value, writer)
299 } else {
300 Err(SerializeError::Custom("Invalid Result state".into()))
301 }
302 }
303 (Def::Pointer(_), _) => {
304 let ptr = peek.into_pointer().map_err(|e| {
305 SerializeError::Custom(alloc::format!("Failed to convert to pointer: {}", e))
306 })?;
307 if let Some(inner) = ptr.borrow_inner() {
308 serialize_value(inner, writer)
309 } else {
310 Err(SerializeError::Custom(
311 "Smart pointer without borrow support".into(),
312 ))
313 }
314 }
315 (_, Type::User(UserType::Struct(sd))) => {
316 match sd.kind {
317 StructKind::Unit => {
318 Ok(())
320 }
321 StructKind::Tuple | StructKind::TupleStruct | StructKind::Struct => {
322 let ps = peek.into_struct().map_err(|e| {
324 SerializeError::Custom(alloc::format!("Failed to convert to struct: {}", e))
325 })?;
326 for (_, field_value) in ps.fields_for_serialize() {
327 serialize_value(field_value, writer)?;
328 }
329 Ok(())
330 }
331 }
332 }
333 (_, Type::User(UserType::Enum(et))) => {
334 let pe = peek.into_enum().map_err(|e| {
335 SerializeError::Custom(alloc::format!("Failed to convert to enum: {}", e))
336 })?;
337 let variant = pe
338 .active_variant()
339 .map_err(|_| SerializeError::Custom("Failed to get active variant".into()))?;
340 let variant_idx = et
341 .variants
342 .iter()
343 .position(|v| v.name == variant.name)
344 .unwrap_or(0);
345
346 write_varint(variant_idx as u64, writer)?;
348
349 if variant.data.fields.is_empty() {
350 Ok(())
352 } else {
353 for (_, field_value) in pe.fields_for_serialize() {
355 serialize_value(field_value, writer)?;
356 }
357 Ok(())
358 }
359 }
360 (_, Type::Pointer(_)) => {
361 if let Some(s) = peek.as_str() {
363 write_varint(s.len() as u64, writer)?;
364 writer.write_bytes(s.as_bytes())
365 } else if let Some(bytes) = peek.as_bytes() {
366 write_varint(bytes.len() as u64, writer)?;
367 writer.write_bytes(bytes)
368 } else {
369 let innermost = peek.innermost_peek();
370 if innermost.shape() != peek.shape() {
371 serialize_value(innermost, writer)
372 } else {
373 Err(SerializeError::Custom("Unknown pointer type".into()))
374 }
375 }
376 }
377 _ => Err(SerializeError::Custom(alloc::format!(
378 "Unsupported type: {:?}",
379 peek.shape().ty
380 ))),
381 }
382}
383
384fn serialize_scalar<W: Writer>(peek: Peek<'_, '_>, writer: &mut W) -> Result<(), SerializeError> {
386 use facet_reflect::ScalarType;
387
388 #[cfg(feature = "camino")]
392 if peek.shape().type_identifier == "Utf8PathBuf" {
393 use camino::Utf8PathBuf;
394 let path = peek.get::<Utf8PathBuf>().map_err(|e| {
395 SerializeError::Custom(alloc::format!("Failed to get Utf8PathBuf: {}", e))
396 })?;
397 let s = path.as_str();
398 write_varint(s.len() as u64, writer)?;
399 return writer.write_bytes(s.as_bytes());
400 }
401 #[cfg(feature = "camino")]
402 if peek.shape().type_identifier == "Utf8Path" {
403 use camino::Utf8Path;
404 let path = peek
405 .get::<Utf8Path>()
406 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get Utf8Path: {}", e)))?;
407 let s = path.as_str();
408 write_varint(s.len() as u64, writer)?;
409 return writer.write_bytes(s.as_bytes());
410 }
411
412 #[cfg(feature = "uuid")]
414 if peek.shape().type_identifier == "Uuid" {
415 use uuid::Uuid;
416 let uuid = peek
417 .get::<Uuid>()
418 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get Uuid: {}", e)))?;
419 return writer.write_bytes(uuid.as_bytes());
420 }
421
422 #[cfg(feature = "ulid")]
424 if peek.shape().type_identifier == "Ulid" {
425 use ulid::Ulid;
426 let ulid = peek
427 .get::<Ulid>()
428 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get Ulid: {}", e)))?;
429 return writer.write_bytes(&ulid.to_bytes());
430 }
431
432 #[cfg(feature = "jiff02")]
434 if peek.shape().type_identifier == "Zoned" {
435 use jiff::Zoned;
436 let zoned = peek
437 .get::<Zoned>()
438 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get Zoned: {}", e)))?;
439 let s = zoned.to_string();
440 write_varint(s.len() as u64, writer)?;
441 return writer.write_bytes(s.as_bytes());
442 }
443 #[cfg(feature = "jiff02")]
444 if peek.shape().type_identifier == "Timestamp" {
445 use jiff::Timestamp;
446 let ts = peek.get::<Timestamp>().map_err(|e| {
447 SerializeError::Custom(alloc::format!("Failed to get Timestamp: {}", e))
448 })?;
449 let s = ts.to_string();
450 write_varint(s.len() as u64, writer)?;
451 return writer.write_bytes(s.as_bytes());
452 }
453 #[cfg(feature = "jiff02")]
454 if peek.shape().type_identifier == "DateTime" {
455 use jiff::civil::DateTime;
456 let dt = peek
457 .get::<DateTime>()
458 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get DateTime: {}", e)))?;
459 let s = dt.to_string();
460 write_varint(s.len() as u64, writer)?;
461 return writer.write_bytes(s.as_bytes());
462 }
463
464 #[cfg(feature = "chrono")]
466 if peek.shape().type_identifier == "DateTime<Utc>" {
467 use chrono::{DateTime, SecondsFormat, Utc};
468 let dt = peek.get::<DateTime<Utc>>().map_err(|e| {
469 SerializeError::Custom(alloc::format!("Failed to get DateTime<Utc>: {}", e))
470 })?;
471 let s = dt.to_rfc3339_opts(SecondsFormat::AutoSi, true);
472 write_varint(s.len() as u64, writer)?;
473 return writer.write_bytes(s.as_bytes());
474 }
475 #[cfg(feature = "chrono")]
476 if peek.shape().type_identifier == "DateTime<Local>" {
477 use chrono::{DateTime, Local, SecondsFormat};
478 let dt = peek.get::<DateTime<Local>>().map_err(|e| {
479 SerializeError::Custom(alloc::format!("Failed to get DateTime<Local>: {}", e))
480 })?;
481 let s = dt.to_rfc3339_opts(SecondsFormat::AutoSi, false);
482 write_varint(s.len() as u64, writer)?;
483 return writer.write_bytes(s.as_bytes());
484 }
485 #[cfg(feature = "chrono")]
486 if peek.shape().type_identifier == "DateTime<FixedOffset>" {
487 use chrono::{DateTime, FixedOffset, SecondsFormat};
488 let dt = peek.get::<DateTime<FixedOffset>>().map_err(|e| {
489 SerializeError::Custom(alloc::format!("Failed to get DateTime<FixedOffset>: {}", e))
490 })?;
491 let s = dt.to_rfc3339_opts(SecondsFormat::AutoSi, false);
492 write_varint(s.len() as u64, writer)?;
493 return writer.write_bytes(s.as_bytes());
494 }
495 #[cfg(feature = "chrono")]
496 if peek.shape().type_identifier == "NaiveDateTime" {
497 use chrono::NaiveDateTime;
498 let dt = peek.get::<NaiveDateTime>().map_err(|e| {
499 SerializeError::Custom(alloc::format!("Failed to get NaiveDateTime: {}", e))
500 })?;
501 let s = dt.format("%Y-%m-%dT%H:%M:%S").to_string();
503 write_varint(s.len() as u64, writer)?;
504 return writer.write_bytes(s.as_bytes());
505 }
506 #[cfg(feature = "chrono")]
507 if peek.shape().type_identifier == "NaiveDate" {
508 use chrono::NaiveDate;
509 let date = peek.get::<NaiveDate>().map_err(|e| {
510 SerializeError::Custom(alloc::format!("Failed to get NaiveDate: {}", e))
511 })?;
512 let s = date.to_string();
513 write_varint(s.len() as u64, writer)?;
514 return writer.write_bytes(s.as_bytes());
515 }
516 #[cfg(feature = "chrono")]
517 if peek.shape().type_identifier == "NaiveTime" {
518 use chrono::NaiveTime;
519 let time = peek.get::<NaiveTime>().map_err(|e| {
520 SerializeError::Custom(alloc::format!("Failed to get NaiveTime: {}", e))
521 })?;
522 let s = time.to_string();
523 write_varint(s.len() as u64, writer)?;
524 return writer.write_bytes(s.as_bytes());
525 }
526
527 #[cfg(feature = "time")]
529 if peek.shape().type_identifier == "UtcDateTime" {
530 use time::UtcDateTime;
531 let dt = peek.get::<UtcDateTime>().map_err(|e| {
532 SerializeError::Custom(alloc::format!("Failed to get UtcDateTime: {}", e))
533 })?;
534 let s = dt
535 .format(&time::format_description::well_known::Rfc3339)
536 .unwrap_or_else(|_| "<invalid>".to_string());
537 write_varint(s.len() as u64, writer)?;
538 return writer.write_bytes(s.as_bytes());
539 }
540 #[cfg(feature = "time")]
541 if peek.shape().type_identifier == "OffsetDateTime" {
542 use time::OffsetDateTime;
543 let dt = peek.get::<OffsetDateTime>().map_err(|e| {
544 SerializeError::Custom(alloc::format!("Failed to get OffsetDateTime: {}", e))
545 })?;
546 let s = dt
547 .format(&time::format_description::well_known::Rfc3339)
548 .unwrap_or_else(|_| "<invalid>".to_string());
549 write_varint(s.len() as u64, writer)?;
550 return writer.write_bytes(s.as_bytes());
551 }
552
553 #[cfg(feature = "ordered-float")]
555 if peek.shape().type_identifier == "OrderedFloat" {
556 if let Some(inner_shape) = peek.shape().inner {
558 if inner_shape.is_type::<f32>() {
559 use ordered_float::OrderedFloat;
560 let val = peek.get::<OrderedFloat<f32>>().map_err(|e| {
561 SerializeError::Custom(alloc::format!("Failed to get OrderedFloat<f32>: {}", e))
562 })?;
563 return writer.write_bytes(&val.0.to_le_bytes());
564 } else if inner_shape.is_type::<f64>() {
565 use ordered_float::OrderedFloat;
566 let val = peek.get::<OrderedFloat<f64>>().map_err(|e| {
567 SerializeError::Custom(alloc::format!("Failed to get OrderedFloat<f64>: {}", e))
568 })?;
569 return writer.write_bytes(&val.0.to_le_bytes());
570 }
571 }
572 }
573
574 #[cfg(feature = "ordered-float")]
576 if peek.shape().type_identifier == "NotNan" {
577 if let Some(inner_shape) = peek.shape().inner {
579 if inner_shape.is_type::<f32>() {
580 use ordered_float::NotNan;
581 let val = peek.get::<NotNan<f32>>().map_err(|e| {
582 SerializeError::Custom(alloc::format!("Failed to get NotNan<f32>: {}", e))
583 })?;
584 return writer.write_bytes(&val.into_inner().to_le_bytes());
585 } else if inner_shape.is_type::<f64>() {
586 use ordered_float::NotNan;
587 let val = peek.get::<NotNan<f64>>().map_err(|e| {
588 SerializeError::Custom(alloc::format!("Failed to get NotNan<f64>: {}", e))
589 })?;
590 return writer.write_bytes(&val.into_inner().to_le_bytes());
591 }
592 }
593 }
594
595 match peek.scalar_type() {
596 Some(ScalarType::Unit) => Ok(()),
597 Some(ScalarType::Bool) => {
598 let v = *peek
599 .get::<bool>()
600 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get bool: {}", e)))?;
601 writer.write_byte(if v { 1 } else { 0 })
602 }
603 Some(ScalarType::Char) => {
604 let c = *peek
605 .get::<char>()
606 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get char: {}", e)))?;
607 let mut buf = [0; 4];
608 let s = c.encode_utf8(&mut buf);
609 write_varint(s.len() as u64, writer)?;
610 writer.write_bytes(s.as_bytes())
611 }
612 Some(ScalarType::Str) => {
613 let s = peek
614 .get::<str>()
615 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get str: {}", e)))?;
616 write_varint(s.len() as u64, writer)?;
617 writer.write_bytes(s.as_bytes())
618 }
619 Some(ScalarType::String) => {
620 let s = peek.get::<alloc::string::String>().map_err(|e| {
621 SerializeError::Custom(alloc::format!("Failed to get String: {}", e))
622 })?;
623 write_varint(s.len() as u64, writer)?;
624 writer.write_bytes(s.as_bytes())
625 }
626 Some(ScalarType::CowStr) => {
627 let s = peek.get::<Cow<'_, str>>().map_err(|e| {
628 SerializeError::Custom(alloc::format!("Failed to get Cow<str>: {}", e))
629 })?;
630 write_varint(s.len() as u64, writer)?;
631 writer.write_bytes(s.as_bytes())
632 }
633 Some(ScalarType::F32) => {
634 let v = *peek
635 .get::<f32>()
636 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get f32: {}", e)))?;
637 writer.write_bytes(&v.to_le_bytes())
638 }
639 Some(ScalarType::F64) => {
640 let v = *peek
641 .get::<f64>()
642 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get f64: {}", e)))?;
643 writer.write_bytes(&v.to_le_bytes())
644 }
645 Some(ScalarType::U8) => {
646 let v = *peek
647 .get::<u8>()
648 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get u8: {}", e)))?;
649 writer.write_byte(v)
650 }
651 Some(ScalarType::U16) => {
652 let v = *peek
653 .get::<u16>()
654 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get u16: {}", e)))?;
655 write_varint(v as u64, writer)
656 }
657 Some(ScalarType::U32) => {
658 let v = *peek
659 .get::<u32>()
660 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get u32: {}", e)))?;
661 write_varint(v as u64, writer)
662 }
663 Some(ScalarType::U64) => {
664 let v = *peek
665 .get::<u64>()
666 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get u64: {}", e)))?;
667 write_varint(v, writer)
668 }
669 Some(ScalarType::U128) => {
670 let v = *peek
671 .get::<u128>()
672 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get u128: {}", e)))?;
673 write_varint_u128(v, writer)
674 }
675 Some(ScalarType::USize) => {
676 let v = *peek.get::<usize>().map_err(|e| {
677 SerializeError::Custom(alloc::format!("Failed to get usize: {}", e))
678 })?;
679 write_varint(v as u64, writer)
680 }
681 Some(ScalarType::I8) => {
682 let v = *peek
683 .get::<i8>()
684 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get i8: {}", e)))?;
685 writer.write_byte(v as u8)
686 }
687 Some(ScalarType::I16) => {
688 let v = *peek
689 .get::<i16>()
690 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get i16: {}", e)))?;
691 write_varint_signed(v as i64, writer)
692 }
693 Some(ScalarType::I32) => {
694 let v = *peek
695 .get::<i32>()
696 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get i32: {}", e)))?;
697 write_varint_signed(v as i64, writer)
698 }
699 Some(ScalarType::I64) => {
700 let v = *peek
701 .get::<i64>()
702 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get i64: {}", e)))?;
703 write_varint_signed(v, writer)
704 }
705 Some(ScalarType::I128) => {
706 let v = *peek
707 .get::<i128>()
708 .map_err(|e| SerializeError::Custom(alloc::format!("Failed to get i128: {}", e)))?;
709 write_varint_signed_i128(v, writer)
710 }
711 Some(ScalarType::ISize) => {
712 let v = *peek.get::<isize>().map_err(|e| {
713 SerializeError::Custom(alloc::format!("Failed to get isize: {}", e))
714 })?;
715 write_varint_signed(v as i64, writer)
716 }
717 #[cfg(feature = "net")]
719 Some(ScalarType::IpAddr) => {
720 let v = *peek.get::<core::net::IpAddr>().map_err(|e| {
721 SerializeError::Custom(alloc::format!("Failed to get IpAddr: {}", e))
722 })?;
723 let s = alloc::format!("{}", v);
724 write_varint(s.len() as u64, writer)?;
725 writer.write_bytes(s.as_bytes())
726 }
727 #[cfg(feature = "net")]
728 Some(ScalarType::Ipv4Addr) => {
729 let v = *peek.get::<core::net::Ipv4Addr>().map_err(|e| {
730 SerializeError::Custom(alloc::format!("Failed to get Ipv4Addr: {}", e))
731 })?;
732 let s = alloc::format!("{}", v);
733 write_varint(s.len() as u64, writer)?;
734 writer.write_bytes(s.as_bytes())
735 }
736 #[cfg(feature = "net")]
737 Some(ScalarType::Ipv6Addr) => {
738 let v = *peek.get::<core::net::Ipv6Addr>().map_err(|e| {
739 SerializeError::Custom(alloc::format!("Failed to get Ipv6Addr: {}", e))
740 })?;
741 let s = alloc::format!("{}", v);
742 write_varint(s.len() as u64, writer)?;
743 writer.write_bytes(s.as_bytes())
744 }
745 #[cfg(feature = "net")]
746 Some(ScalarType::SocketAddr) => {
747 let v = *peek.get::<core::net::SocketAddr>().map_err(|e| {
748 SerializeError::Custom(alloc::format!("Failed to get SocketAddr: {}", e))
749 })?;
750 let s = alloc::format!("{}", v);
751 write_varint(s.len() as u64, writer)?;
752 writer.write_bytes(s.as_bytes())
753 }
754 Some(scalar_type) => Err(SerializeError::Custom(alloc::format!(
755 "Unsupported scalar type: {:?}",
756 scalar_type
757 ))),
758 None => {
759 #[cfg(feature = "bytestring")]
761 if peek.shape() == <bytestring::ByteString as facet_core::Facet>::SHAPE {
762 let bs = peek.get::<bytestring::ByteString>().map_err(|e| {
763 SerializeError::Custom(alloc::format!("Failed to get ByteString: {}", e))
764 })?;
765 let s: &str = bs.as_ref();
766 write_varint(s.len() as u64, writer)?;
767 return writer.write_bytes(s.as_bytes());
768 }
769
770 #[cfg(feature = "compact_str")]
772 if peek.shape() == <compact_str::CompactString as facet_core::Facet>::SHAPE {
773 let cs = peek.get::<compact_str::CompactString>().map_err(|e| {
774 SerializeError::Custom(alloc::format!("Failed to get CompactString: {}", e))
775 })?;
776 let s: &str = cs.as_str();
777 write_varint(s.len() as u64, writer)?;
778 return writer.write_bytes(s.as_bytes());
779 }
780
781 #[cfg(feature = "smartstring")]
783 if peek.shape()
784 == <smartstring::SmartString<smartstring::LazyCompact> as facet_core::Facet>::SHAPE
785 {
786 let ss = peek
787 .get::<smartstring::SmartString<smartstring::LazyCompact>>()
788 .map_err(|e| {
789 SerializeError::Custom(alloc::format!("Failed to get SmartString: {}", e))
790 })?;
791 let s: &str = ss.as_str();
792 write_varint(s.len() as u64, writer)?;
793 return writer.write_bytes(s.as_bytes());
794 }
795
796 if let Some(s) = peek.as_str() {
798 write_varint(s.len() as u64, writer)?;
799 writer.write_bytes(s.as_bytes())
800 } else if peek.shape().vtable.has_display() {
801 let s = alloc::format!("{}", peek);
803 write_varint(s.len() as u64, writer)?;
804 writer.write_bytes(s.as_bytes())
805 } else {
806 Err(SerializeError::Custom(alloc::format!(
807 "Unknown scalar type: {}",
808 peek.shape().type_identifier
809 )))
810 }
811 }
812 }
813}
814
815fn write_varint<W: Writer>(mut value: u64, writer: &mut W) -> Result<(), SerializeError> {
817 loop {
818 let mut byte = (value & 0x7F) as u8;
819 value >>= 7;
820 if value != 0 {
821 byte |= 0x80;
822 }
823 writer.write_byte(byte)?;
824 if value == 0 {
825 break;
826 }
827 }
828 Ok(())
829}
830
831fn write_varint_u128<W: Writer>(mut value: u128, writer: &mut W) -> Result<(), SerializeError> {
833 loop {
834 let mut byte = (value & 0x7F) as u8;
835 value >>= 7;
836 if value != 0 {
837 byte |= 0x80;
838 }
839 writer.write_byte(byte)?;
840 if value == 0 {
841 break;
842 }
843 }
844 Ok(())
845}
846
847fn write_varint_signed<W: Writer>(value: i64, writer: &mut W) -> Result<(), SerializeError> {
849 let encoded = ((value << 1) ^ (value >> 63)) as u64;
851 write_varint(encoded, writer)
852}
853
854fn write_varint_signed_i128<W: Writer>(value: i128, writer: &mut W) -> Result<(), SerializeError> {
856 let encoded = ((value << 1) ^ (value >> 127)) as u128;
858 write_varint_u128(encoded, writer)
859}
860
861#[cfg(test)]
862mod tests {
863 use super::*;
864 use facet::Facet;
865 use postcard::to_allocvec as postcard_to_vec;
866 use serde::Serialize;
867
868 #[derive(Facet, Serialize, PartialEq, Debug)]
869 struct SimpleStruct {
870 a: u32,
871 b: alloc::string::String,
872 c: bool,
873 }
874
875 #[test]
876 fn test_simple_struct() {
877 facet_testhelpers::setup();
878
879 let value = SimpleStruct {
880 a: 123,
881 b: "hello".into(),
882 c: true,
883 };
884
885 let facet_bytes = to_vec(&value).unwrap();
886 let postcard_bytes = postcard_to_vec(&value).unwrap();
887
888 assert_eq!(facet_bytes, postcard_bytes);
889 }
890
891 #[test]
892 fn test_u8() {
893 facet_testhelpers::setup();
894
895 #[derive(Facet, Serialize, PartialEq, Debug)]
896 struct U8Struct {
897 value: u8,
898 }
899
900 let value = U8Struct { value: 42 };
901 let facet_bytes = to_vec(&value).unwrap();
902 let postcard_bytes = postcard_to_vec(&value).unwrap();
903 assert_eq!(facet_bytes, postcard_bytes);
904 }
905
906 #[test]
907 fn test_i32() {
908 facet_testhelpers::setup();
909
910 #[derive(Facet, Serialize, PartialEq, Debug)]
911 struct I32Struct {
912 value: i32,
913 }
914
915 let value = I32Struct { value: -100000 };
916 let facet_bytes = to_vec(&value).unwrap();
917 let postcard_bytes = postcard_to_vec(&value).unwrap();
918 assert_eq!(facet_bytes, postcard_bytes);
919 }
920
921 #[test]
922 fn test_string() {
923 facet_testhelpers::setup();
924
925 #[derive(Facet, Serialize, PartialEq, Debug)]
926 struct StringStruct {
927 value: alloc::string::String,
928 }
929
930 let value = StringStruct {
931 value: "hello world".into(),
932 };
933 let facet_bytes = to_vec(&value).unwrap();
934 let postcard_bytes = postcard_to_vec(&value).unwrap();
935 assert_eq!(facet_bytes, postcard_bytes);
936 }
937
938 #[test]
939 fn test_vec() {
940 facet_testhelpers::setup();
941
942 #[derive(Facet, Serialize, PartialEq, Debug)]
943 struct VecStruct {
944 values: Vec<u32>,
945 }
946
947 let value = VecStruct {
948 values: alloc::vec![1, 2, 3, 4, 5],
949 };
950 let facet_bytes = to_vec(&value).unwrap();
951 let postcard_bytes = postcard_to_vec(&value).unwrap();
952 assert_eq!(facet_bytes, postcard_bytes);
953 }
954
955 #[test]
956 fn test_option_some() {
957 facet_testhelpers::setup();
958
959 #[derive(Facet, Serialize, PartialEq, Debug)]
960 struct OptionStruct {
961 value: Option<u32>,
962 }
963
964 let value = OptionStruct { value: Some(42) };
965 let facet_bytes = to_vec(&value).unwrap();
966 let postcard_bytes = postcard_to_vec(&value).unwrap();
967 assert_eq!(facet_bytes, postcard_bytes);
968 }
969
970 #[test]
971 fn test_option_none() {
972 facet_testhelpers::setup();
973
974 #[derive(Facet, Serialize, PartialEq, Debug)]
975 struct OptionStruct {
976 value: Option<u32>,
977 }
978
979 let value = OptionStruct { value: None };
980 let facet_bytes = to_vec(&value).unwrap();
981 let postcard_bytes = postcard_to_vec(&value).unwrap();
982 assert_eq!(facet_bytes, postcard_bytes);
983 }
984
985 #[test]
986 fn test_unit_enum() {
987 facet_testhelpers::setup();
988
989 #[derive(Facet, Serialize, PartialEq, Debug)]
990 #[repr(C)]
991 enum Color {
992 Red,
993 Green,
994 Blue,
995 }
996
997 let facet_bytes = to_vec(&Color::Red).unwrap();
998 let postcard_bytes = postcard_to_vec(&Color::Red).unwrap();
999 assert_eq!(facet_bytes, postcard_bytes);
1000
1001 let facet_bytes = to_vec(&Color::Green).unwrap();
1002 let postcard_bytes = postcard_to_vec(&Color::Green).unwrap();
1003 assert_eq!(facet_bytes, postcard_bytes);
1004
1005 let facet_bytes = to_vec(&Color::Blue).unwrap();
1006 let postcard_bytes = postcard_to_vec(&Color::Blue).unwrap();
1007 assert_eq!(facet_bytes, postcard_bytes);
1008 }
1009
1010 #[test]
1011 fn test_tuple_enum() {
1012 facet_testhelpers::setup();
1013
1014 #[derive(Facet, Serialize, PartialEq, Debug)]
1015 #[repr(C)]
1016 enum Value {
1017 Int(i32),
1018 Text(alloc::string::String),
1019 }
1020
1021 let facet_bytes = to_vec(&Value::Int(42)).unwrap();
1022 let postcard_bytes = postcard_to_vec(&Value::Int(42)).unwrap();
1023 assert_eq!(facet_bytes, postcard_bytes);
1024
1025 let facet_bytes = to_vec(&Value::Text("hello".into())).unwrap();
1026 let postcard_bytes = postcard_to_vec(&Value::Text("hello".into())).unwrap();
1027 assert_eq!(facet_bytes, postcard_bytes);
1028 }
1029
1030 #[test]
1031 fn test_struct_enum() {
1032 facet_testhelpers::setup();
1033
1034 #[derive(Facet, Serialize, PartialEq, Debug)]
1035 #[repr(C)]
1036 enum Message {
1037 Quit,
1038 Move { x: i32, y: i32 },
1039 }
1040
1041 let facet_bytes = to_vec(&Message::Quit).unwrap();
1042 let postcard_bytes = postcard_to_vec(&Message::Quit).unwrap();
1043 assert_eq!(facet_bytes, postcard_bytes);
1044
1045 let facet_bytes = to_vec(&Message::Move { x: 10, y: 20 }).unwrap();
1046 let postcard_bytes = postcard_to_vec(&Message::Move { x: 10, y: 20 }).unwrap();
1047 assert_eq!(facet_bytes, postcard_bytes);
1048 }
1049
1050 #[test]
1051 fn test_to_writer_fallible() {
1052 facet_testhelpers::setup();
1053
1054 struct CustomWriter {
1055 buffer: Vec<u8>,
1056 }
1057
1058 impl Writer for CustomWriter {
1059 fn write_byte(&mut self, byte: u8) -> Result<(), SerializeError> {
1060 self.buffer.push(byte);
1061 Ok(())
1062 }
1063
1064 fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), SerializeError> {
1065 self.buffer.extend_from_slice(bytes);
1066 Ok(())
1067 }
1068 }
1069
1070 let value = SimpleStruct {
1071 a: 123,
1072 b: "hello".into(),
1073 c: true,
1074 };
1075
1076 let mut writer = CustomWriter { buffer: Vec::new() };
1077 to_writer_fallible(&value, &mut writer).unwrap();
1078
1079 let postcard_bytes = postcard_to_vec(&value).unwrap();
1080 assert_eq!(writer.buffer, postcard_bytes);
1081 }
1082}