Skip to content

Commit e64f767

Browse files
authored
Merge branch 'main' into schema-for-cow
2 parents b5936c9 + a83c294 commit e64f767

File tree

4 files changed

+40
-8
lines changed

4 files changed

+40
-8
lines changed

source/postcard-schema/src/impls/builtins_alloc.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,35 @@ use crate::{schema::DataModelType, Schema};
44

55
extern crate alloc;
66

7+
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "use-std"))))]
78
impl<T: Schema> Schema for alloc::vec::Vec<T> {
89
const SCHEMA: &'static DataModelType = &DataModelType::Seq(T::SCHEMA);
910
}
1011

12+
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "use-std"))))]
1113
impl Schema for alloc::string::String {
1214
const SCHEMA: &'static DataModelType = &DataModelType::String;
1315
}
1416

17+
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "use-std"))))]
1518
impl<K: Schema, V: Schema> Schema for alloc::collections::BTreeMap<K, V> {
1619
const SCHEMA: &'static DataModelType = &DataModelType::Map {
1720
key: K::SCHEMA,
1821
val: V::SCHEMA,
1922
};
2023
}
2124

25+
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "use-std"))))]
2226
impl<K: Schema> Schema for alloc::collections::BTreeSet<K> {
2327
const SCHEMA: &'static DataModelType = &DataModelType::Seq(K::SCHEMA);
2428
}
2529

30+
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "use-std"))))]
31+
impl<T: Schema> Schema for alloc::boxed::Box<T> {
32+
const SCHEMA: &'static DataModelType = T::SCHEMA;
33+
}
34+
35+
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "use-std"))))]
2636
impl<T: ?Sized + Schema + alloc::borrow::ToOwned> Schema for alloc::borrow::Cow<'_, T> {
2737
const SCHEMA: &'static DataModelType = T::SCHEMA;
2838
}

source/postcard-schema/src/impls/builtins_std.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ impl<K: Schema> Schema for std::collections::BTreeSet<K> {
4343
const SCHEMA: &'static DataModelType = &DataModelType::Seq(K::SCHEMA);
4444
}
4545

46+
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "use-std"))))]
47+
impl<T: Schema> Schema for std::boxed::Box<T> {
48+
const SCHEMA: &'static DataModelType = T::SCHEMA;
49+
}
50+
4651
#[cfg_attr(docsrs, doc(cfg(any(feature = "alloc", feature = "use-std"))))]
4752
impl<T: ?Sized + Schema + std::borrow::ToOwned> Schema for std::borrow::Cow<'_, T> {
4853
const SCHEMA: &'static DataModelType = T::SCHEMA;

source/postcard/src/de/flavors.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,10 @@ pub struct Slice<'de> {
138138
impl<'de> Slice<'de> {
139139
/// Create a new [Slice] from the given buffer
140140
pub fn new(sli: &'de [u8]) -> Self {
141+
let range = sli.as_ptr_range();
141142
Self {
142-
cursor: sli.as_ptr(),
143-
end: unsafe { sli.as_ptr().add(sli.len()) },
143+
cursor: range.start,
144+
end: range.end,
144145
_pl: PhantomData,
145146
}
146147
}
@@ -155,6 +156,8 @@ impl<'de> Flavor<'de> for Slice<'de> {
155156
if self.cursor == self.end {
156157
Err(Error::DeserializeUnexpectedEnd)
157158
} else {
159+
// SAFETY: `self.cursor` is in-bounds and won't be incremented past `self.end` as we
160+
// have checked above.
158161
unsafe {
159162
let res = Ok(*self.cursor);
160163
self.cursor = self.cursor.add(1);
@@ -174,6 +177,8 @@ impl<'de> Flavor<'de> for Slice<'de> {
174177
if remain < ct {
175178
Err(Error::DeserializeUnexpectedEnd)
176179
} else {
180+
// SAFETY: `self.cursor` is valid for `ct` elements and won't be incremented past `self.end` as we
181+
// have checked above.
177182
unsafe {
178183
let sli = core::slice::from_raw_parts(self.cursor, ct);
179184
self.cursor = self.cursor.add(ct);
@@ -185,6 +190,7 @@ impl<'de> Flavor<'de> for Slice<'de> {
185190
/// Return the remaining (unused) bytes in the Deserializer
186191
fn finalize(self) -> Result<&'de [u8]> {
187192
let remain = (self.end as usize) - (self.cursor as usize);
193+
// SAFETY: `self.cursor` is valid for `remain` elements
188194
unsafe { Ok(core::slice::from_raw_parts(self.cursor, remain)) }
189195
}
190196
}
@@ -207,9 +213,10 @@ pub mod io {
207213

208214
impl<'de> SlidingBuffer<'de> {
209215
pub fn new(sli: &'de mut [u8]) -> Self {
216+
let range = sli.as_mut_ptr_range();
210217
Self {
211-
cursor: sli.as_mut_ptr(),
212-
end: unsafe { sli.as_ptr().add(sli.len()) },
218+
cursor: range.start,
219+
end: range.end,
213220
_pl: PhantomData,
214221
}
215222
}
@@ -225,6 +232,8 @@ pub mod io {
225232
let buff = if remain < ct {
226233
return Err(Error::DeserializeUnexpectedEnd);
227234
} else {
235+
// SAFETY: `self.cursor` is valid for `ct` elements and won't be incremented
236+
// past `self.end` as we have checked above.
228237
unsafe {
229238
let sli = core::slice::from_raw_parts_mut(self.cursor, ct);
230239
self.cursor = self.cursor.add(ct);
@@ -237,6 +246,7 @@ pub mod io {
237246

238247
fn complete(self) -> Result<&'de mut [u8]> {
239248
let remain = (self.end as usize) - (self.cursor as usize);
249+
// SAFETY: `self.cursor` is valid for `remain` elements
240250
unsafe { Ok(core::slice::from_raw_parts_mut(self.cursor, remain)) }
241251
}
242252
}

source/postcard/src/ser/flavors.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,11 @@ pub struct Slice<'a> {
146146
impl<'a> Slice<'a> {
147147
/// Create a new `Slice` flavor from a given backing buffer
148148
pub fn new(buf: &'a mut [u8]) -> Self {
149-
let ptr = buf.as_mut_ptr();
149+
let ptr = buf.as_mut_ptr_range();
150150
Slice {
151-
start: ptr,
152-
cursor: ptr,
153-
end: unsafe { ptr.add(buf.len()) },
151+
start: ptr.start,
152+
cursor: ptr.start,
153+
end: ptr.end,
154154
_pl: PhantomData,
155155
}
156156
}
@@ -164,6 +164,8 @@ impl<'a> Flavor for Slice<'a> {
164164
if self.cursor == self.end {
165165
Err(Error::SerializeBufferFull)
166166
} else {
167+
// SAFETY: `self.cursor` is in-bounds and won't be incremented past `self.end` as we
168+
// have checked above.
167169
unsafe {
168170
self.cursor.write(b);
169171
self.cursor = self.cursor.add(1);
@@ -179,6 +181,8 @@ impl<'a> Flavor for Slice<'a> {
179181
if blen > remain {
180182
Err(Error::SerializeBufferFull)
181183
} else {
184+
// SAFETY: `self.cursor` is in-bounds for `blen` elements and won't be incremented past
185+
// `self.end` as we have checked above.
182186
unsafe {
183187
core::ptr::copy_nonoverlapping(b.as_ptr(), self.cursor, blen);
184188
self.cursor = self.cursor.add(blen);
@@ -189,6 +193,7 @@ impl<'a> Flavor for Slice<'a> {
189193

190194
fn finalize(self) -> Result<Self::Output> {
191195
let used = (self.cursor as usize) - (self.start as usize);
196+
// SAFETY: `self.cursor` is in-bounds for `used` elements
192197
let sli = unsafe { core::slice::from_raw_parts_mut(self.start, used) };
193198
Ok(sli)
194199
}
@@ -200,6 +205,7 @@ impl Index<usize> for Slice<'_> {
200205
fn index(&self, idx: usize) -> &u8 {
201206
let len = (self.end as usize) - (self.start as usize);
202207
assert!(idx < len);
208+
// SAFETY: `self.start` is in-bounds at `idx`
203209
unsafe { &*self.start.add(idx) }
204210
}
205211
}
@@ -208,6 +214,7 @@ impl IndexMut<usize> for Slice<'_> {
208214
fn index_mut(&mut self, idx: usize) -> &mut u8 {
209215
let len = (self.end as usize) - (self.start as usize);
210216
assert!(idx < len);
217+
// SAFETY: `self.start` is in-bounds at `idx`
211218
unsafe { &mut *self.start.add(idx) }
212219
}
213220
}

0 commit comments

Comments
 (0)