Skip to main content

rapx/cli/
verify.rs

1use clap::Args;
2
3#[derive(Debug, Clone, Copy, clap::ValueEnum)]
4pub enum VerifyMode {
5    #[value(help = "Auto-detect: verify all functions with unsafe callees or struct invariants")]
6    Scan,
7    #[value(help = "Only verify functions annotated with #[rapx::verify]")]
8    Targeted,
9}
10
11/// Postfix repeat count: `auto` (default) enables automatic loop-depth
12/// detection; a number N ≥ 0 sets a fixed repeat count.
13#[derive(Debug, Clone)]
14pub enum PostfixRepeat {
15    Auto,
16    Fixed(usize),
17}
18
19impl std::fmt::Display for PostfixRepeat {
20    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21        match self {
22            PostfixRepeat::Auto => write!(f, "auto"),
23            PostfixRepeat::Fixed(n) => write!(f, "{n}"),
24        }
25    }
26}
27
28impl std::str::FromStr for PostfixRepeat {
29    type Err = String;
30    fn from_str(s: &str) -> Result<Self, Self::Err> {
31        if s.eq_ignore_ascii_case("auto") {
32            Ok(PostfixRepeat::Auto)
33        } else {
34            s.parse::<usize>()
35                .map(PostfixRepeat::Fixed)
36                .map_err(|_| format!("expected 'auto' or a non-negative integer, got '{s}'"))
37        }
38    }
39}
40
41/// Arguments for the `verify` command.
42#[derive(Debug, Clone, Args)]
43pub struct VerifyArgs {
44    /// Identify all functions annotated with #[rapx::verify] and print each target, its unsafe callees, and their safety contracts.
45    #[arg(long)]
46    pub prepare_targets: bool,
47    /// Number of extra SCC postfix repetitions allowed during path enumeration.
48    /// `auto` (default): automatic loop-depth detection for InBound and Align.
49    /// A number ≥ 0 sets a fixed repeat count.
50    #[arg(long, default_value = "auto", value_parser = clap::value_parser!(PostfixRepeat))]
51    pub postfix_repeat: PostfixRepeat,
52    /// Verification mode: `scan` auto-detects unannotated unsafe targets (default), `targeted` verifies #[rapx::verify] functions.
53    #[arg(long, default_value = "scan")]
54    pub mode: VerifyMode,
55    /// Skip struct invariant checks and derive safety via constructor-mutator-method chains.
56    /// Works with both `scan` and `targeted` modes.
57    #[arg(long)]
58    pub skip_invariant: bool,
59    /// Filter verification targets to only those within the specified crate
60    /// (Rust crate name or Cargo package name, e.g. `std`, `core`, `my-crate`).
61    /// Useful for standard-library workspaces and sub-workspaces.
62    #[arg(long = "crate")]
63    pub crate_name: Option<String>,
64    /// Filter verification targets to only those within the specified module path
65    /// (e.g. `my_module::inner`). When combined with `--crate`, the path is
66    /// interpreted relative to that crate. Applies to all verification modes.
67    #[arg(long)]
68    pub module: Option<String>,
69    /// Print all contract resolutions for every verification target: each
70    /// unsafe callee with its resolved contracts, and the caller's own
71    /// contracts (expanded form).  Useful for debugging missing or unexpected
72    /// contract resolutions.
73    #[arg(long)]
74    pub debug_contracts: bool,
75}