use super::{GenerationError, MAX_SAFE_INTEGER};
use crate::Limits;
use serde_json::{Value, json};
pub fn method_limits(request: Limits, response: Limits) -> Result<Value, GenerationError> {
let value = json!({
"requestBytes":request.bytes, "requestNodes":request.nodes, "requestDepth":request.depth,
"responseBytes":response.bytes, "responseNodes":response.nodes, "responseDepth":response.depth
});
validate(&value)?;
Ok(value)
}
pub fn payload_limits(limits: Limits) -> Result<Value, GenerationError> {
let value = json!({"bytes":limits.bytes,"nodes":limits.nodes,"depth":limits.depth});
validate_payload(&value)?;
Ok(value)
}
pub(super) fn validate_payload(payload: &Value) -> Result<(), GenerationError> {
for (key, minimum) in [("bytes", 0), ("nodes", 1), ("depth", 1)] {
allowance(&payload[key], minimum)?;
}
Ok(())
}
fn allowance(value: &Value, minimum: u64) -> Result<(), GenerationError> {
let n = value.as_u64().ok_or(GenerationError::Complexity)?;
if n > MAX_SAFE_INTEGER {
return Err(GenerationError::Complexity);
}
if n < minimum {
return Err(GenerationError::Limits);
}
Ok(())
}
pub(super) fn validate(method: &Value) -> Result<(), GenerationError> {
for key in [
"requestBytes",
"responseBytes",
"requestNodes",
"responseNodes",
"requestDepth",
"responseDepth",
] {
let minimum = if key.ends_with("Bytes") {
crate::contract::HEADER as u64
} else {
1
};
allowance(&method[key], minimum)?;
}
Ok(())
}