value_bag/
fill.rs
1use crate::std::fmt;
42
43use super::internal::{Internal, InternalVisitor};
44use super::{Error, ValueBag};
45
46impl<'v> ValueBag<'v> {
47 pub const fn from_fill<T>(value: &'v T) -> Self
49 where
50 T: Fill,
51 {
52 ValueBag {
53 inner: Internal::Fill(value),
54 }
55 }
56}
57
58pub trait Fill {
64 fn fill(&self, slot: Slot) -> Result<(), Error>;
66}
67
68impl<F> Fill for F
69where
70 F: Fn(Slot) -> Result<(), Error>,
71{
72 fn fill(&self, slot: Slot) -> Result<(), Error> {
73 (self)(slot)
74 }
75}
76
77pub struct Slot<'s, 'f> {
79 visitor: &'s mut dyn InternalVisitor<'f>,
80}
81
82impl<'s, 'f> fmt::Debug for Slot<'s, 'f> {
83 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
84 f.debug_struct("Slot").finish()
85 }
86}
87
88impl<'s, 'f> Slot<'s, 'f> {
89 pub(crate) fn new(visitor: &'s mut dyn InternalVisitor<'f>) -> Self {
90 Slot { visitor }
91 }
92
93 pub(crate) fn fill<F>(self, f: F) -> Result<(), Error>
94 where
95 F: FnOnce(&mut dyn InternalVisitor<'f>) -> Result<(), Error>,
96 {
97 f(self.visitor)
98 }
99
100 pub fn fill_any<T>(self, value: T) -> Result<(), Error>
104 where
105 T: Into<ValueBag<'f>>,
106 {
107 self.fill(|visitor| value.into().inner.internal_visit(visitor))
108 }
109}
110
111#[cfg(test)]
112mod tests {
113 #[cfg(target_arch = "wasm32")]
114 use wasm_bindgen_test::*;
115
116 use super::*;
117 use crate::std::string::ToString;
118
119 #[test]
120 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
121 fn fill_value_borrowed() {
122 struct TestFill;
123
124 impl Fill for TestFill {
125 fn fill(&self, slot: Slot) -> Result<(), Error> {
126 let dbg = &1 as &dyn fmt::Debug;
127
128 slot.fill_debug(dbg)
129 }
130 }
131
132 assert_eq!("1", ValueBag::from_fill(&TestFill).to_string());
133 }
134
135 #[test]
136 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
137 fn fill_cast() {
138 struct TestFill;
139
140 impl Fill for TestFill {
141 fn fill(&self, slot: Slot) -> Result<(), Error> {
142 slot.fill_any("a string")
143 }
144 }
145
146 assert_eq!(
147 "a string",
148 ValueBag::from_fill(&TestFill)
149 .to_borrowed_str()
150 .expect("invalid value")
151 );
152 }
153
154 #[test]
155 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
156 fn fill_fn_cast() {
157 assert_eq!(
158 42u64,
159 ValueBag::from_fill(&|slot: Slot| slot.fill_any(42u64))
160 .to_u64()
161 .unwrap()
162 );
163 }
164
165 #[test]
166 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
167 fn fill_fn_borrowed() {
168 #[derive(Debug)]
169 struct MyValue;
170
171 let value = MyValue;
172 assert_eq!(
173 format!("{:?}", value),
174 format!(
175 "{:?}",
176 ValueBag::from_fill(&|slot: Slot| slot.fill_debug(&value))
177 )
178 );
179 }
180}