1#![cfg_attr(not(feature = "std"), no_std)]
2#![warn(missing_docs)]
3#![warn(clippy::std_instead_of_core)]
4#![warn(clippy::std_instead_of_alloc)]
5#![doc = include_str!("../README.md")]
6
7#[cfg(feature = "alloc")]
10extern crate alloc;
11
12use facet_core::{Facet, TypeNameOpts};
13
14mod value;
15pub use value::*;
16
17mod struct_;
18pub use struct_::*;
19
20mod enum_;
21pub use enum_::*;
22
23mod list;
24pub use list::*;
25
26mod map;
27pub use map::*;
28
29mod option;
30pub use option::*;
31
32use facet_core::{Def, OpaqueConst, Shape};
33
34#[derive(Clone, Copy)]
39#[non_exhaustive]
40pub enum Peek<'mem> {
41 Value(PeekValue<'mem>),
43
44 List(PeekList<'mem>),
46
47 Map(PeekMap<'mem>),
49
50 Struct(PeekStruct<'mem>),
52
53 Enum(PeekEnum<'mem>),
55
56 Option(PeekOption<'mem>),
58}
59
60impl<'mem> core::ops::Deref for Peek<'mem> {
61 type Target = PeekValue<'mem>;
62
63 fn deref(&self) -> &Self::Target {
64 match self {
65 Peek::Value(value) => value,
66 Peek::List(list) => list,
67 Peek::Map(map) => map,
68 Peek::Struct(struct_) => struct_,
69 Peek::Enum(enum_) => enum_,
70 Peek::Option(option) => option,
71 }
72 }
73}
74
75impl<'mem> Peek<'mem> {
76 pub fn new<S: Facet>(s: &'mem S) -> Self {
78 let data = OpaqueConst::new(s);
81 unsafe { Self::unchecked_new(data, S::SHAPE) }
82 }
83
84 pub unsafe fn unchecked_new(data: OpaqueConst<'mem>, shape: &'static Shape) -> Self {
91 let value = unsafe { PeekValue::unchecked_new(data, shape) };
92 match shape.def {
93 Def::Struct(def) => Peek::Struct(PeekStruct::new(value, def)),
94 Def::Map(def) => Peek::Map(PeekMap::new(value, def)),
95 Def::List(def) => Peek::List(PeekList::new(value, def)),
96 Def::Scalar { .. } => Peek::Value(value),
97 Def::Enum(def) => Peek::Enum(PeekEnum::new(value, def)),
98 Def::Option(def) => Peek::Option(PeekOption::new(value, def)),
99 _ => todo!("unsupported def: {:?}", shape.def),
100 }
101 }
102
103 pub fn as_value(self) -> PeekValue<'mem> {
105 match self {
106 Self::Value(v) => v,
107 Self::List(l) => *l,
108 Self::Map(m) => *m,
109 Self::Struct(s) => *s,
110 Self::Enum(e) => *e,
111 Self::Option(o) => *o,
112 }
113 }
114}
115
116impl core::fmt::Debug for Peek<'_> {
117 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
118 let value = self.as_value();
119 if value.debug(f).is_none() {
120 value.type_name(f, TypeNameOpts::infinite())?;
121 write!(f, "(⋯)")?;
122 }
123 Ok(())
124 }
125}
126
127impl core::fmt::Display for Peek<'_> {
128 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
129 let value = self.as_value();
130 if value.display(f).is_none() {
131 value.type_name(f, TypeNameOpts::infinite())?;
132 write!(f, "(⋯)")?;
133 }
134 Ok(())
135 }
136}