Comments (3)
80% solution:
pub fn borsh_len(value: &impl BorshSerialize) -> Result<usize> {
struct Writer {
len: usize,
}
impl Write for Writer {
#[inline]
fn write(&mut self, buf: &[u8]) -> Result<usize> {
self.len += buf.len();
Ok(buf.len())
}
#[inline]
fn flush(&mut self) -> Result<()> {
Ok(())
}
}
let mut w = Writer { len: 0 };
value.serialize(&mut w)?;
Ok(w.len)
}
This won't do exactly what we want for types that use extra heap-allocated buffers for serilization, but my gut feeling is that that's rare.
EDIT: didnt' resist the temptation to look at the asm, looks right for simple cases:
15:22:23|~/projects/borsh-rs|master⚡✚*
λ git diff --cached
diff --git a/borsh/examples/len.rs b/borsh/examples/len.rs
new file mode 100644
index 00000000..69b84a0c
--- /dev/null
+++ b/borsh/examples/len.rs
@@ -0,0 +1,17 @@
+#[derive(borsh::BorshSerialize)]
+pub struct Foo {
+ x: u8,
+ y: u32
+}
+
+#[no_mangle]
+#[inline(never)]
+pub fn size_of_foo(foo: &Foo) -> usize {
+ borsh::len(foo).unwrap_or_default()
+}
+
+fn main() {
+ let foo = Foo { x: 62, y: 92 };
+ let res = size_of_foo(&foo);
+ eprintln!("{}", res);
+}
diff --git a/borsh/src/lib.rs b/borsh/src/lib.rs
index 51c81919..55088283 100644
--- a/borsh/src/lib.rs
+++ b/borsh/src/lib.rs
@@ -45,3 +45,23 @@ pub mod maybestd {
pub use hashbrown::hash_map::Entry;
}
}
+
+pub fn len(value: &impl BorshSerialize) -> std::io::Result<usize> {
+ struct Writer {
+ len: usize,
+ }
+ impl std::io::Write for Writer {
+ #[inline]
+ fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
+ self.len += buf.len();
+ Ok(buf.len())
+ }
+ #[inline]
+ fn flush(&mut self) -> std::io::Result<()> {
+ Ok(())
+ }
+ }
+ let mut w = Writer { len: 0 };
+ value.serialize(&mut w)?;
+ Ok(w.len)
+}
15:22:28|~/projects/borsh-rs|master⚡✚*
λ cargo build --example len --release -q
15:22:41|~/projects/borsh-rs|master⚡✚*
λ dis ./target/release/examples/len size_of_foo
Dump of assembler code for function size_of_foo:
0x0000000000011b70 <+0>: mov eax,0x5
0x0000000000011b75 <+5>: ret
End of assembler dump.
from borsh-rs.
And output for slightly more intersting
#[derive(borsh::BorshSerialize)]
pub struct Foo {
x: u8,
y: u32,
zs: Vec<u32>,
}
Dump of assembler code for function size_of_foo:
0x0000000000011be0 <+0>: mov rax,QWORD PTR [rdi+0x10]
0x0000000000011be4 <+4>: mov rcx,rax
0x0000000000011be7 <+7>: shr rcx,0x20
0x0000000000011beb <+11>: test rax,rax
0x0000000000011bee <+14>: lea rax,[rax*4+0x9]
0x0000000000011bf6 <+22>: mov edx,0x9
0x0000000000011bfb <+27>: cmovne rdx,rax
0x0000000000011bff <+31>: xor eax,eax
0x0000000000011c01 <+33>: test rcx,rcx
0x0000000000011c04 <+36>: cmove rax,rdx
0x0000000000011c08 <+40>: ret
End of assembler dump.
from borsh-rs.
What a trick :D
from borsh-rs.
Related Issues (20)
- FR: Provide a way to borrow data from a slice. HOT 4
- Enum discriminant is not serialized when specified HOT 1
- Adding Async support HOT 14
- Introduce a required `#[borsh(use_discriminant = true|false)]` enum attribute when discriminants are specified HOT 4
- Introduce snapshot testing for all the serialized results HOT 1
- Document borsh crate features HOT 1
- create minimal benches for sets/maps
- `BorshSerialize` failure to compile derive with `#[borsh_skip]` on struct variant field HOT 1
- `insta` tests for prettified `TokenStream`-s in `borsh*derive-internal`
- More than 256 enum variants HOT 2
- Support for serde::{Serialize, Deserialize} HOT 7
- Add a test or two on `#[borsh_init(init)]` logic
- Update near/near-abi-rs to work with alpha release
- Update zeropoolnetwork/bn to work with alpha release HOT 1
- BorshSchema vs custom serialisation HOT 4
- Include discriminant number in `BorshSchema::Enum::variants`
- Rename declarations (tuples, `nil`, `string`, `nonzero_xx` and arrays) HOT 5
- add implementation for `BorshSerialize`, `BorshDeserialize`, `BorshSchema` for `char` HOT 3
- Security Policy violation Branch Protection HOT 2
- Security Policy violation SECURITY.md HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from borsh-rs.