|
20 | 20 | //! * truncating the sequence of assembled octets happens through
|
21 | 21 | //! [`Truncate`].
|
22 | 22 |
|
| 23 | +use core::fmt; |
23 | 24 | use core::convert::Infallible;
|
24 | 25 | #[cfg(feature = "bytes")] use bytes::{Bytes, BytesMut};
|
25 | 26 | #[cfg(feature = "std")] use std::borrow::Cow;
|
@@ -212,6 +213,31 @@ impl<A: smallvec::Array<Item = u8>> OctetsBuilder for smallvec::SmallVec<A> {
|
212 | 213 | }
|
213 | 214 | }
|
214 | 215 |
|
| 216 | +#[cfg(feature = "heapless")] |
| 217 | +impl<const N: usize> OctetsBuilder for heapless::Vec<u8, N> { |
| 218 | + type Octets = Self; |
| 219 | + type BuildError<E> = ShortBuild<E>; |
| 220 | + type AppendResult<T> = Result<T, ShortBuf>; |
| 221 | + |
| 222 | + fn try_append_slice( |
| 223 | + &mut self, slice: &[u8] |
| 224 | + ) -> Result<(), Self::BuildError<Infallible>> { |
| 225 | + self.extend_from_slice(slice).map_err(|_| ShortBuild::ShortBuf) |
| 226 | + } |
| 227 | + |
| 228 | + fn len(&self) -> usize { |
| 229 | + self.as_slice().len() |
| 230 | + } |
| 231 | + |
| 232 | + fn is_empty(&self) -> bool { |
| 233 | + self.len() == 0 |
| 234 | + } |
| 235 | + |
| 236 | + fn freeze(self) -> Self::Octets { |
| 237 | + self |
| 238 | + } |
| 239 | +} |
| 240 | + |
215 | 241 | //------------ EmptyBuilder --------------------------------------------------
|
216 | 242 |
|
217 | 243 | /// An octets builder that can be newly created empty.
|
@@ -262,6 +288,18 @@ impl<A: smallvec::Array<Item = u8>> EmptyBuilder for smallvec::SmallVec<A> {
|
262 | 288 | }
|
263 | 289 | }
|
264 | 290 |
|
| 291 | +#[cfg(feature = "heapless")] |
| 292 | +impl<const N: usize> EmptyBuilder for heapless::Vec<u8, N> { |
| 293 | + fn empty() -> Self { |
| 294 | + Self::new() |
| 295 | + } |
| 296 | + |
| 297 | + fn with_capacity(capacity: usize) -> Self { |
| 298 | + debug_assert!(capacity <= N); |
| 299 | + Self::with_capacity(capacity) |
| 300 | + } |
| 301 | +} |
| 302 | + |
265 | 303 | //------------ IntoBuilder ---------------------------------------------------
|
266 | 304 |
|
267 | 305 | /// An octets type that can be converted into an octets builder.
|
@@ -321,6 +359,15 @@ impl<A: smallvec::Array<Item = u8>> IntoBuilder for smallvec::SmallVec<A> {
|
321 | 359 | }
|
322 | 360 | }
|
323 | 361 |
|
| 362 | +#[cfg(feature = "heapless")] |
| 363 | +impl<const N: usize> IntoBuilder for heapless::Vec<u8, N> { |
| 364 | + type Builder = Self; |
| 365 | + |
| 366 | + fn into_builder(self) -> Self::Builder { |
| 367 | + self |
| 368 | + } |
| 369 | +} |
| 370 | + |
324 | 371 |
|
325 | 372 | //------------ FromBuilder ---------------------------------------------------
|
326 | 373 |
|
@@ -369,6 +416,15 @@ impl<A: smallvec::Array<Item = u8>> FromBuilder for smallvec::SmallVec<A> {
|
369 | 416 | }
|
370 | 417 | }
|
371 | 418 |
|
| 419 | +#[cfg(feature = "heapless")] |
| 420 | +impl<const N: usize> FromBuilder for heapless::Vec<u8, N> { |
| 421 | + type Builder = Self; |
| 422 | + |
| 423 | + fn from_builder(builder: Self::Builder) -> Self { |
| 424 | + builder |
| 425 | + } |
| 426 | +} |
| 427 | + |
372 | 428 |
|
373 | 429 | //============ Error Handling ================================================
|
374 | 430 |
|
@@ -413,3 +469,75 @@ impl<T, E, U: CollapseResult<T, E>> Collapse<U> for Result<T, E> {
|
413 | 469 | }
|
414 | 470 | }
|
415 | 471 |
|
| 472 | + |
| 473 | +//------------ ShortBuf ------------------------------------------------------ |
| 474 | + |
| 475 | +/// An attempt was made to write beyond the end of a buffer. |
| 476 | +/// |
| 477 | +/// This type is returned as an error by all functions and methods that append |
| 478 | +/// data to an [octets builder] when the buffer size of the builder is not |
| 479 | +/// sufficient to append the data. |
| 480 | +/// |
| 481 | +/// [octets builder]: trait.OctetsBuilder.html |
| 482 | +#[derive(Clone, Debug, Eq, PartialEq)] |
| 483 | +pub struct ShortBuf; |
| 484 | + |
| 485 | + |
| 486 | +//--- From and CollapseResult |
| 487 | + |
| 488 | +impl From<Infallible> for ShortBuf { |
| 489 | + fn from(_: Infallible) -> ShortBuf { |
| 490 | + unreachable!() |
| 491 | + } |
| 492 | +} |
| 493 | + |
| 494 | +impl<T> CollapseResult<T, ShortBuild<Infallible>> for Result<T, ShortBuf> { |
| 495 | + fn collapse_result(src: Result<T, ShortBuild<Infallible>>) -> Self { |
| 496 | + src.map_err(|err| match err { |
| 497 | + ShortBuild::ShortBuf => ShortBuf, |
| 498 | + ShortBuild::Build(_) => unreachable!() |
| 499 | + }) |
| 500 | + } |
| 501 | +} |
| 502 | + |
| 503 | + |
| 504 | +//--- Display and Error |
| 505 | + |
| 506 | +impl fmt::Display for ShortBuf { |
| 507 | + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 508 | + f.write_str("buffer size exceeded") |
| 509 | + } |
| 510 | +} |
| 511 | + |
| 512 | +#[cfg(feature = "std")] |
| 513 | +impl std::error::Error for ShortBuf {} |
| 514 | + |
| 515 | + |
| 516 | +//------------ ShortBuild ---------------------------------------------------- |
| 517 | + |
| 518 | +#[derive(Clone, Debug)] |
| 519 | +pub enum ShortBuild<T> { |
| 520 | + Build(T), |
| 521 | + ShortBuf, |
| 522 | +} |
| 523 | + |
| 524 | +impl<T> From<T> for ShortBuild<T> { |
| 525 | + fn from(t: T) -> Self { |
| 526 | + ShortBuild::Build(t) |
| 527 | + } |
| 528 | +} |
| 529 | + |
| 530 | +//--- Display and Error |
| 531 | + |
| 532 | +impl<T: fmt::Display> fmt::Display for ShortBuild<T> { |
| 533 | + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 534 | + match self { |
| 535 | + ShortBuild::Build(t) => t.fmt(f), |
| 536 | + ShortBuild::ShortBuf => ShortBuf.fmt(f) |
| 537 | + } |
| 538 | + } |
| 539 | +} |
| 540 | + |
| 541 | +#[cfg(feature = "std")] |
| 542 | +impl<T: fmt::Debug + fmt::Display> std::error::Error for ShortBuild<T> {} |
| 543 | + |
0 commit comments