-
Notifications
You must be signed in to change notification settings - Fork 19
Open
Description
Right now if the raw bytes parse correctly, the next step in most applications is to validate (sanitize) the data. This being an additional step is a risk (programmer may forget about validation) and waste of resources (protocol
has to parse all fields before sanitation can run). It may also result in unnecessary allocations - let's say our protocol accepts Vec<_>
and someone sends us 8GB of data. protocol
will download, parse and allocate 8GB Vec
, which will be rejected by the next instruction like if vec.len() > 64 { return; }
.
I imagine code could look like this:
#[derive(Protocol)]
pub struct User {
pub name: String,
pub pub_key: [u8; 64],
}
impl User {
fn validate_name(name: String) -> bool { /* some code */ }
fn validate_pub_key(pub_key: [u8; 64]) -> bool { /* some code */ }
}
User::parse( // or `User::validate_from_raw_bytes`
&data,
&protocol::Settings::default()
).unwrap();
Alternatively, protocol
could generate trait, so we could have different ways of validating the same struct, and stateful validators:
#[derive(Protocol)]
pub struct User {
pub name: String,
pub pub_key: [u8; 64],
}
// protocol generates:
//
// trait UserValidate {
// fn validate_name(&mut self, name: String) -> bool;
// fn validate_pub_key(&mut self, pub_key: [u8; 64]) -> bool;
// }
struct UserBasicValidator;
impl UserValidate for UserBasicValidator {
fn validate_name(&mut self, name: String) -> bool { /* some code */ }
fn validate_pub_key(&mut self, pub_key: [u8; 64]) -> bool { /* some code */ }
}
User::parse(
&data,
&protocol::Settings::default(),
UserBasicValidator::new(),
).unwrap();
Metadata
Metadata
Assignees
Labels
No labels