use core::fmt;
const DEFAULT_BYTE_BUDGET: usize = 16_777_216;
pub const DEFAULT_MAX_SOURCE_LEN: SourceByteLimit = SourceByteLimit::new(DEFAULT_BYTE_BUDGET);
pub const DEFAULT_MAX_CODE_LINE_LEN: CodeLineByteLimit =
CodeLineByteLimit::new(DEFAULT_BYTE_BUDGET);
pub const DEFAULT_MAX_PAYLOAD_LEN: PayloadByteLimit = PayloadByteLimit::new(DEFAULT_BYTE_BUDGET);
pub const DEFAULT_MAX_RULES: RuleLimit = RuleLimit::new(1_000_000);
pub const DEFAULT_MAX_STEPS: StepLimit = StepLimit::new(1_000_000);
pub const DEFAULT_MAX_STATE_LEN: RuntimeStateByteLimit =
RuntimeStateByteLimit::new(DEFAULT_BYTE_BUDGET);
pub const DEFAULT_MAX_INPUT_LEN: RuntimeInputByteLimit =
RuntimeInputByteLimit::new(DEFAULT_BYTE_BUDGET);
pub const DEFAULT_MAX_RETURN_LEN: ReturnByteLimit = ReturnByteLimit::new(DEFAULT_BYTE_BUDGET);
pub const DEFAULT_MAX_TRACE_SNAPSHOT_LEN: TraceSnapshotByteLimit =
TraceSnapshotByteLimit::new(DEFAULT_BYTE_BUDGET);
pub const DEFAULT_PARSE_LIMITS: ParseLimits = ParseLimits::new(
DEFAULT_MAX_SOURCE_LEN,
DEFAULT_MAX_CODE_LINE_LEN,
DEFAULT_MAX_PAYLOAD_LEN,
DEFAULT_MAX_RULES,
);
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct SourceByteCount {
value: usize,
}
impl SourceByteCount {
#[must_use]
pub(crate) const fn new(value: usize) -> Self {
Self { value }
}
#[must_use]
pub const fn get(self) -> usize {
self.value
}
}
impl fmt::Display for SourceByteCount {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.value.fmt(f)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct CodeLineByteCount {
value: usize,
}
impl CodeLineByteCount {
#[must_use]
pub(crate) const fn new(value: usize) -> Self {
Self { value }
}
#[must_use]
pub const fn get(self) -> usize {
self.value
}
}
impl fmt::Display for CodeLineByteCount {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.value.fmt(f)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct SourceByteLimit {
value: usize,
}
impl SourceByteLimit {
#[must_use]
pub const fn new(value: usize) -> Self {
Self { value }
}
#[must_use]
pub const fn get(self) -> usize {
self.value
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct CodeLineByteLimit {
value: usize,
}
impl CodeLineByteLimit {
#[must_use]
pub const fn new(value: usize) -> Self {
Self { value }
}
#[must_use]
pub const fn get(self) -> usize {
self.value
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct PayloadByteLimit {
value: usize,
}
impl PayloadByteLimit {
#[must_use]
pub const fn new(value: usize) -> Self {
Self { value }
}
#[must_use]
pub const fn get(self) -> usize {
self.value
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct RuleLimit {
value: usize,
}
impl RuleLimit {
#[must_use]
pub const fn new(value: usize) -> Self {
Self { value }
}
#[must_use]
pub const fn get(self) -> usize {
self.value
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ParseLimits {
source_len: SourceByteLimit,
code_line_len: CodeLineByteLimit,
payload_len: PayloadByteLimit,
rules: RuleLimit,
}
impl ParseLimits {
#[must_use]
pub const fn new(
max_source_len: SourceByteLimit,
max_code_line_len: CodeLineByteLimit,
max_payload_len: PayloadByteLimit,
max_rules: RuleLimit,
) -> Self {
Self {
source_len: max_source_len,
code_line_len: max_code_line_len,
payload_len: max_payload_len,
rules: max_rules,
}
}
#[must_use]
pub const fn source_byte_limit(self) -> SourceByteLimit {
self.source_len
}
#[must_use]
pub const fn code_line_byte_limit(self) -> CodeLineByteLimit {
self.code_line_len
}
#[must_use]
pub const fn payload_byte_limit(self) -> PayloadByteLimit {
self.payload_len
}
#[must_use]
pub const fn rule_limit(self) -> RuleLimit {
self.rules
}
#[must_use]
pub const fn with_source_byte_limit(mut self, max_source_len: SourceByteLimit) -> Self {
self.source_len = max_source_len;
self
}
#[must_use]
pub const fn with_code_line_byte_limit(mut self, max_code_line_len: CodeLineByteLimit) -> Self {
self.code_line_len = max_code_line_len;
self
}
#[must_use]
pub const fn with_payload_byte_limit(mut self, max_payload_len: PayloadByteLimit) -> Self {
self.payload_len = max_payload_len;
self
}
#[must_use]
pub const fn with_rule_limit(mut self, max_rules: RuleLimit) -> Self {
self.rules = max_rules;
self
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StepLimit {
value: usize,
}
impl StepLimit {
#[must_use]
pub const fn new(value: usize) -> Self {
Self { value }
}
#[must_use]
pub const fn get(self) -> usize {
self.value
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct RuntimeStateByteLimit {
value: usize,
}
impl RuntimeStateByteLimit {
#[must_use]
pub const fn new(value: usize) -> Self {
Self { value }
}
#[must_use]
pub const fn get(self) -> usize {
self.value
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct RuntimeInputByteLimit {
value: usize,
}
impl RuntimeInputByteLimit {
#[must_use]
pub const fn new(value: usize) -> Self {
Self { value }
}
#[must_use]
pub const fn get(self) -> usize {
self.value
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ReturnByteLimit {
value: usize,
}
impl ReturnByteLimit {
#[must_use]
pub const fn new(value: usize) -> Self {
Self { value }
}
#[must_use]
pub const fn get(self) -> usize {
self.value
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct TraceSnapshotByteLimit {
value: usize,
}
impl TraceSnapshotByteLimit {
#[must_use]
pub const fn new(value: usize) -> Self {
Self { value }
}
#[must_use]
pub const fn get(self) -> usize {
self.value
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct StepCount {
value: usize,
}
impl StepCount {
pub(crate) const ZERO: Self = Self { value: 0 };
#[must_use]
pub const fn get(self) -> usize {
self.value
}
pub(crate) fn checked_next(self) -> Option<Self> {
let value = self.value.checked_add(1)?;
Some(Self { value })
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RunLimits {
steps: StepLimit,
state_len: RuntimeStateByteLimit,
return_len: ReturnByteLimit,
}
impl RunLimits {
#[must_use]
pub const fn new(
max_steps: StepLimit,
max_state_len: RuntimeStateByteLimit,
max_return_len: ReturnByteLimit,
) -> Self {
Self {
steps: max_steps,
state_len: max_state_len,
return_len: max_return_len,
}
}
#[must_use]
pub const fn step_limit(self) -> StepLimit {
self.steps
}
#[must_use]
pub const fn state_byte_limit(self) -> RuntimeStateByteLimit {
self.state_len
}
#[must_use]
pub const fn return_byte_limit(self) -> ReturnByteLimit {
self.return_len
}
#[must_use]
pub const fn with_step_limit(mut self, max_steps: StepLimit) -> Self {
self.steps = max_steps;
self
}
#[must_use]
pub const fn with_state_byte_limit(mut self, max_state_len: RuntimeStateByteLimit) -> Self {
self.state_len = max_state_len;
self
}
#[must_use]
pub const fn with_return_byte_limit(mut self, max_return_len: ReturnByteLimit) -> Self {
self.return_len = max_return_len;
self
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct TraceSnapshotLimits {
run: RunLimits,
snapshot: TraceSnapshotByteLimit,
}
impl TraceSnapshotLimits {
#[must_use]
pub const fn new(run_limits: RunLimits, snapshot_byte_limit: TraceSnapshotByteLimit) -> Self {
Self {
run: run_limits,
snapshot: snapshot_byte_limit,
}
}
#[must_use]
pub const fn run_limits(self) -> RunLimits {
self.run
}
#[must_use]
pub const fn snapshot_byte_limit(self) -> TraceSnapshotByteLimit {
self.snapshot
}
}