SoftbearStudios / SoftbearStudios/bitcode
Implement #[bitcode(with = LocalType)] RemoteType
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 671
- Forks
- 61
- PR merge metrics
- No merged PRs in 30d
Description
#47 has not yet been implemented due to complexity surrounding:
serde::Serialize::serializecan return errors, butbitcode::encodecan't, we would have to panic.serde::Deserialize::deserializecan return errors, but luckilybitcode::decodecan as well. Unfortunately, we would have to implement infrastructure for dropping T's owned bybitcode::Decoders while keeping the decoders themselves alive. Keeping unsafe code involving drop panic-safe is a non-trivial task.
Therefore, a simpler alternative to get most bitcode users unstuck would be something like
use bespoke_string::CompactZeroCopyArcStr;
#[derive(bitcode::Encode, bitcode::Decode)]
struct User {
#[bitcode(with = LocalString)]
first_name: CompactZeroCopyArcStr,
// If you wanted a different encoder and decoder type (e.g. non &str types cannot borrow during decode).
#[bitcode(encode_with = LocalString, decode_with = LocalString)]
last_name: CompactZeroCopyArcStr,
}
#[derive(bitcode::Encode, bitcode::Decode)]
struct LocalString<'a>(&'a str);
impl<'a> From<&'a CompactZeroCopyArcStr> for LocalString<'a> {
fn from(v: &'a CompactZeroCopyArcStr) -> Self {
Self(v.as_str())
}
}
impl From<LocalString<'_>> for CompactZeroCopyArcStr {
fn from(v: LocalString) -> Self {
Self::new(v.0)
}
}
See also:
https://github.com/SoftbearStudios/bitcode/issues/13
https://docs.rs/serde_with
https://rkyv.org/derive-macro-features/remote-derive.html
To avoid the complexity present with #47, you would not be able to return errors during decoding.
If such an error did occur, you would have to construct a zero value of the type. Some examples:
- Time outside range, return the zero time
- FiniteVec has too many elements, return an empty vec
- OsString/CString has invalid characters, return an empty string
If for some reason you needed to know if an error occurred (not just handling decoding untrusted bytes from the network), you could store the error out of band in a thread_local and check for errors after decode.
Important: Panicking during decode and using catch_unwind is not a valid implementation of error handling. Bitcode relies on in place initialization during decode for performance, so any panics during decode result in leaked memory.
Currently the only way to observe this with the public API is to panic in PartialEq, Ord, or Hash inside the HashMap and BTreeMap decoders.
Because this feature would present a larger surface for accidently leaking memory, it's probably best for bitcode to catch_unwind (in at least debug mode) and cause the process to abort with an error message explaining the issue.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing issue #47, the public bitcode::Encode and bitcode::Decode APIs, and the serde::Serialize and serde::Deserialize behavior described here. Done means supporting #[bitcode(with = ...)] and separate encode_with/decode_with types without relying on panic-based error handling or unsafe decoder lifetime handling.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100