/rust/registry/src/index.crates.io-6f17d22bba15001f/scroll-0.10.2/src/pwrite.rs
Line | Count | Source (jump to first uncovered line) |
1 | | use core::result; |
2 | | use core::ops::{Index, IndexMut, RangeFrom}; |
3 | | |
4 | | use crate::ctx::{TryIntoCtx, MeasureWith}; |
5 | | use crate::error; |
6 | | |
7 | | /// A very generic, contextual pwrite interface in Rust. |
8 | | /// |
9 | | /// Like [Pread](trait.Pread.html) — but for writing! |
10 | | /// |
11 | | /// Implementing `Pwrite` on a data store allows you to then write almost arbitrarily complex types |
12 | | /// efficiently. |
13 | | /// |
14 | | /// To this end the Pwrite trait works in conjuction with the [TryIntoCtx](ctx/trait.TryIntoCtx.html); |
15 | | /// The `TryIntoCtx` trait implemented on a type defines how to convert said type into data that |
16 | | /// an implementation of Pwrite can … well … write. |
17 | | /// |
18 | | /// As with [Pread](trait.Pread.html) 'data' does not necessarily mean `&[u8]` but can be any |
19 | | /// indexable type. In fact much of the documentation of `Pread` applies to `Pwrite` as well just |
20 | | /// with 'read' switched for 'write' and 'From' switched with 'Into' so if you haven't yet you |
21 | | /// should read the documentation of `Pread` first. |
22 | | /// |
23 | | /// Unless you need to implement your own data store — that is either can't convert to `&[u8]` or |
24 | | /// have a data that is not `&[u8]` — you will probably want to implement |
25 | | /// [TryIntoCtx](ctx/trait.TryIntoCtx.html) on your Rust types to be written. |
26 | | /// |
27 | | pub trait Pwrite<Ctx, E> : Index<usize> + IndexMut<RangeFrom<usize>> + MeasureWith<Ctx> |
28 | | where |
29 | | Ctx: Copy, |
30 | | E: From<error::Error>, |
31 | | { |
32 | 24.3k | fn pwrite<N: TryIntoCtx<Ctx, <Self as Index<RangeFrom<usize>>>::Output, Error = E>>(&mut self, n: N, offset: usize) -> result::Result<usize, E> where Ctx: Default { |
33 | 24.3k | self.pwrite_with(n, offset, Ctx::default()) |
34 | 24.3k | } Unexecuted instantiation: <_ as scroll::pwrite::Pwrite<_, _>>::pwrite::<_> <[u8] as scroll::pwrite::Pwrite<scroll::endian::Endian, scroll::error::Error>>::pwrite::<u64> Line | Count | Source | 32 | 24.3k | fn pwrite<N: TryIntoCtx<Ctx, <Self as Index<RangeFrom<usize>>>::Output, Error = E>>(&mut self, n: N, offset: usize) -> result::Result<usize, E> where Ctx: Default { | 33 | 24.3k | self.pwrite_with(n, offset, Ctx::default()) | 34 | 24.3k | } |
|
35 | | /// Write `N` at offset `I` with context `Ctx` |
36 | | /// # Example |
37 | | /// ``` |
38 | | /// use scroll::{Pwrite, Pread, LE}; |
39 | | /// let mut bytes: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0]; |
40 | | /// bytes.pwrite_with::<u32>(0xbeefbeef, 0, LE).unwrap(); |
41 | | /// assert_eq!(bytes.pread_with::<u32>(0, LE).unwrap(), 0xbeefbeef); |
42 | 24.3k | fn pwrite_with<N: TryIntoCtx<Ctx, <Self as Index<RangeFrom<usize>>>::Output, Error = E>>(&mut self, n: N, offset: usize, ctx: Ctx) -> result::Result<usize, E> { |
43 | 24.3k | let len = self.measure_with(&ctx); |
44 | 24.3k | if offset >= len { |
45 | 192 | return Err(error::Error::BadOffset(offset).into()) |
46 | 24.1k | } |
47 | 24.1k | let dst = &mut self[offset..]; |
48 | 24.1k | n.try_into_ctx(dst, ctx) |
49 | 24.3k | } Unexecuted instantiation: <_ as scroll::pwrite::Pwrite<_, _>>::pwrite_with::<_> <[u8] as scroll::pwrite::Pwrite<scroll::endian::Endian, scroll::error::Error>>::pwrite_with::<u64> Line | Count | Source | 42 | 24.3k | fn pwrite_with<N: TryIntoCtx<Ctx, <Self as Index<RangeFrom<usize>>>::Output, Error = E>>(&mut self, n: N, offset: usize, ctx: Ctx) -> result::Result<usize, E> { | 43 | 24.3k | let len = self.measure_with(&ctx); | 44 | 24.3k | if offset >= len { | 45 | 192 | return Err(error::Error::BadOffset(offset).into()) | 46 | 24.1k | } | 47 | 24.1k | let dst = &mut self[offset..]; | 48 | 24.1k | n.try_into_ctx(dst, ctx) | 49 | 24.3k | } |
|
50 | | /// Write `n` into `self` at `offset`, with a default `Ctx`. Updates the offset. |
51 | | #[inline] |
52 | 0 | fn gwrite<N: TryIntoCtx<Ctx, <Self as Index<RangeFrom<usize>>>::Output, Error = E>>(&mut self, n: N, offset: &mut usize) -> result::Result<usize, E> where |
53 | 0 | Ctx: Default { |
54 | 0 | let ctx = Ctx::default(); |
55 | 0 | self.gwrite_with(n, offset, ctx) |
56 | 0 | } |
57 | | /// Write `n` into `self` at `offset`, with the `ctx`. Updates the offset. |
58 | | #[inline] |
59 | 0 | fn gwrite_with<N: TryIntoCtx<Ctx, <Self as Index<RangeFrom<usize>>>::Output, Error = E>>(&mut self, n: N, offset: &mut usize, ctx: Ctx) -> result::Result<usize, E> { |
60 | 0 | let o = *offset; |
61 | 0 | match self.pwrite_with(n, o, ctx) { |
62 | 0 | Ok(size) => { |
63 | 0 | *offset += size; |
64 | 0 | Ok(size) |
65 | | }, |
66 | 0 | err => err |
67 | | } |
68 | 0 | } |
69 | | } |
70 | | |
71 | | impl<Ctx: Copy, |
72 | | E: From<error::Error>, |
73 | | R: ?Sized + Index<usize> + IndexMut<RangeFrom<usize>> + MeasureWith<Ctx>> |
74 | | Pwrite<Ctx, E> for R {} |