Coverage Report

Created: 2026-06-07 07:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wasmtime/crates/cli-flags/src/opt.rs
Line
Count
Source
1
//! Support for parsing Wasmtime's `-O`, `-W`, etc "option groups"
2
//!
3
//! This builds up a clap-derive-like system where there's ideally a single
4
//! macro `wasmtime_option_group!` which is invoked per-option which enables
5
//! specifying options in a struct-like syntax where all other boilerplate about
6
//! option parsing is contained exclusively within this module.
7
8
use crate::{KeyValuePair, WasiNnGraph};
9
use clap::builder::{StringValueParser, TypedValueParser, ValueParserFactory};
10
use clap::error::{Error, ErrorKind};
11
use serde::de::{self, Visitor};
12
use std::num::NonZeroU32;
13
use std::path::PathBuf;
14
use std::str::FromStr;
15
use std::time::Duration;
16
use std::{fmt, marker};
17
use wasmtime::{Result, bail, format_err};
18
19
/// Characters which can be safely ignored while parsing numeric options to wasmtime
20
const IGNORED_NUMBER_CHARS: [char; 1] = ['_'];
21
22
#[macro_export]
23
macro_rules! wasmtime_option_group {
24
    (
25
        $(#[$attr:meta])*
26
        pub struct $opts:ident {
27
            $(
28
                $(#[doc = $doc:tt])*
29
                $(#[doc($doc_attr:meta)])?
30
                $(#[serde($serde_attr:meta)])*
31
                pub $opt:ident: $container:ident<$payload:ty>,
32
            )+
33
34
            $(
35
                #[prefixed = $prefix:tt]
36
                $(#[serde($serde_attr2:meta)])*
37
                $(#[doc = $prefixed_doc:tt])*
38
                $(#[doc($prefixed_doc_attr:meta)])?
39
                pub $prefixed:ident: Vec<(String, Option<String>)>,
40
            )?
41
        }
42
        enum $option:ident {
43
            ...
44
        }
45
    ) => {
46
        #[derive(Default, Debug)]
47
        $(#[$attr])*
48
        pub struct $opts {
49
            $(
50
                $(#[serde($serde_attr)])*
51
                $(#[doc($doc_attr)])?
52
                pub $opt: $container<$payload>,
53
            )+
54
            $(
55
                $(#[serde($serde_attr2)])*
56
                pub $prefixed: Vec<(String, Option<String>)>,
57
            )?
58
        }
59
60
        #[derive(Clone, PartialEq)]
61
        #[expect(non_camel_case_types, reason = "macro-generated code")]
62
        enum $option {
63
            $(
64
                $opt($payload),
65
            )+
66
            $(
67
                $prefixed(String, Option<String>),
68
            )?
69
        }
70
71
        impl $crate::opt::WasmtimeOption for $option {
72
            const OPTIONS: &'static [$crate::opt::OptionDesc<$option>] = &[
73
                $(
74
                    $crate::opt::OptionDesc {
75
                        name: $crate::opt::OptName::Name(stringify!($opt)),
76
0
                        parse: |_, s| {
77
                            Ok($option::$opt(
78
0
                                $crate::opt::WasmtimeOptionValue::parse(s)?
79
                            ))
80
0
                        },
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#0}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#2}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#3}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#4}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#5}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#6}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#7}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#8}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#9}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#10}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#11}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#38}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#39}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#40}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#41}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#42}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#43}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#44}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#1}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#12}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#13}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#14}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#15}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#16}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#17}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#18}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#19}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#20}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#21}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#22}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#23}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#24}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#25}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#26}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#27}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#28}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#29}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#30}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#31}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#32}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#33}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#34}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#35}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#36}
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#37}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#0}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#2}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#3}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#4}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#5}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#6}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#7}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#8}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#9}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#10}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#11}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#1}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#12}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#13}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#14}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#15}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#16}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#17}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#18}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#19}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#20}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#21}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#22}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#23}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#24}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#25}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#26}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#27}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#28}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#29}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#30}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#31}
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#32}
Unexecuted instantiation: <wasmtime_cli_flags::Record as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#0}
Unexecuted instantiation: <wasmtime_cli_flags::Record as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#2}
Unexecuted instantiation: <wasmtime_cli_flags::Record as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#1}
Unexecuted instantiation: <wasmtime_cli_flags::Codegen as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#0}
Unexecuted instantiation: <wasmtime_cli_flags::Codegen as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#2}
Unexecuted instantiation: <wasmtime_cli_flags::Codegen as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#3}
Unexecuted instantiation: <wasmtime_cli_flags::Codegen as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#4}
Unexecuted instantiation: <wasmtime_cli_flags::Codegen as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#5}
Unexecuted instantiation: <wasmtime_cli_flags::Codegen as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#6}
Unexecuted instantiation: <wasmtime_cli_flags::Codegen as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#7}
Unexecuted instantiation: <wasmtime_cli_flags::Codegen as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#8}
Unexecuted instantiation: <wasmtime_cli_flags::Codegen as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#9}
Unexecuted instantiation: <wasmtime_cli_flags::Codegen as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#1}
Unexecuted instantiation: <wasmtime_cli_flags::Debug as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#0}
Unexecuted instantiation: <wasmtime_cli_flags::Debug as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#2}
Unexecuted instantiation: <wasmtime_cli_flags::Debug as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#3}
Unexecuted instantiation: <wasmtime_cli_flags::Debug as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#4}
Unexecuted instantiation: <wasmtime_cli_flags::Debug as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#5}
Unexecuted instantiation: <wasmtime_cli_flags::Debug as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#6}
Unexecuted instantiation: <wasmtime_cli_flags::Debug as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#7}
Unexecuted instantiation: <wasmtime_cli_flags::Debug as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#8}
Unexecuted instantiation: <wasmtime_cli_flags::Debug as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#9}
Unexecuted instantiation: <wasmtime_cli_flags::Debug as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#10}
Unexecuted instantiation: <wasmtime_cli_flags::Debug as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#11}
Unexecuted instantiation: <wasmtime_cli_flags::Debug as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#1}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#0}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#2}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#3}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#4}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#5}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#6}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#7}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#8}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#9}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#10}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#11}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#38}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#39}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#40}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#41}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#42}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#43}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#44}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#45}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#46}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#47}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#48}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#49}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#1}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#12}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#13}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#14}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#15}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#16}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#17}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#18}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#19}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#20}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#21}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#22}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#23}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#24}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#25}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#26}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#27}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#28}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#29}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#30}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#31}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#32}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#33}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#34}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#35}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#36}
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as wasmtime_cli_flags::opt::WasmtimeOption>::OPTIONS::{closure#37}
81
                        val_help: <$payload as $crate::opt::WasmtimeOptionValue>::VAL_HELP,
82
                        docs: concat!($($doc, "\n",)*),
83
                    },
84
                 )+
85
                $(
86
                    $crate::opt::OptionDesc {
87
                        name: $crate::opt::OptName::Prefix($prefix),
88
0
                        parse: |name, val| {
89
                            Ok($option::$prefixed(
90
0
                                name.to_string(),
91
0
                                val.map(|v| v.to_string()),
92
                            ))
93
0
                        },
94
                        val_help: "[=val]",
95
                        docs: concat!($($prefixed_doc, "\n",)*),
96
                    },
97
                 )?
98
            ];
99
        }
100
101
        impl core::fmt::Display for $option {
102
0
            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
103
0
                match self {
104
                    $(
105
0
                        $option::$opt(val) => {
106
0
                            write!(f, "{}=", stringify!($opt).replace('_', "-"))?;
107
0
                            $crate::opt::WasmtimeOptionValue::display(val, f)
108
                        }
109
                    )+
110
                    $(
111
0
                        $option::$prefixed(key, val) => {
112
0
                            write!(f, "{}-{key}", stringify!($prefixed))?;
113
0
                            if let Some(val) = val {
114
0
                                write!(f, "={val}")?;
115
0
                            }
116
0
                            Ok(())
117
                        }
118
                    )?
119
                }
120
0
            }
Unexecuted instantiation: <wasmtime_cli_flags::Optimize as core::fmt::Display>::fmt
Unexecuted instantiation: <wasmtime_cli_flags::Wasi as core::fmt::Display>::fmt
Unexecuted instantiation: <wasmtime_cli_flags::Record as core::fmt::Display>::fmt
Unexecuted instantiation: <wasmtime_cli_flags::Codegen as core::fmt::Display>::fmt
Unexecuted instantiation: <wasmtime_cli_flags::Debug as core::fmt::Display>::fmt
Unexecuted instantiation: <wasmtime_cli_flags::Wasm as core::fmt::Display>::fmt
121
        }
122
123
        impl $opts {
124
0
            fn configure_with(&mut self, opts: &[$crate::opt::CommaSeparated<$option>]) {
125
0
                for opt in opts.iter().flat_map(|o| o.0.iter()) {
Unexecuted instantiation: <wasmtime_cli_flags::OptimizeOptions>::configure_with::{closure#0}
Unexecuted instantiation: <wasmtime_cli_flags::WasmOptions>::configure_with::{closure#0}
Unexecuted instantiation: <wasmtime_cli_flags::WasiOptions>::configure_with::{closure#0}
Unexecuted instantiation: <wasmtime_cli_flags::RecordOptions>::configure_with::{closure#0}
Unexecuted instantiation: <wasmtime_cli_flags::CodegenOptions>::configure_with::{closure#0}
Unexecuted instantiation: <wasmtime_cli_flags::DebugOptions>::configure_with::{closure#0}
126
0
                    match opt {
127
                        $(
128
0
                            $option::$opt(val) => {
129
0
                                $crate::opt::OptionContainer::push(&mut self.$opt, val.clone());
130
0
                            }
131
                        )+
132
                        $(
133
0
                            $option::$prefixed(key, val) => self.$prefixed.push((key.clone(), val.clone())),
134
                        )?
135
                    }
136
                }
137
0
            }
Unexecuted instantiation: <wasmtime_cli_flags::OptimizeOptions>::configure_with
Unexecuted instantiation: <wasmtime_cli_flags::WasmOptions>::configure_with
Unexecuted instantiation: <wasmtime_cli_flags::WasiOptions>::configure_with
Unexecuted instantiation: <wasmtime_cli_flags::RecordOptions>::configure_with
Unexecuted instantiation: <wasmtime_cli_flags::CodegenOptions>::configure_with
Unexecuted instantiation: <wasmtime_cli_flags::DebugOptions>::configure_with
138
139
0
            fn to_options(&self) -> Vec<$option> {
140
0
                let mut ret = Vec::new();
141
                $(
142
0
                    for item in $crate::opt::OptionContainer::get(&self.$opt) {
143
0
                        ret.push($option::$opt(item.clone()));
144
0
                    }
145
                )+
146
                $(
147
0
                    for (key,val) in self.$prefixed.iter() {
148
0
                        ret.push($option::$prefixed(key.clone(), val.clone()));
149
0
                    }
150
                )?
151
0
                ret
152
0
            }
Unexecuted instantiation: <wasmtime_cli_flags::OptimizeOptions>::to_options
Unexecuted instantiation: <wasmtime_cli_flags::WasmOptions>::to_options
Unexecuted instantiation: <wasmtime_cli_flags::WasiOptions>::to_options
Unexecuted instantiation: <wasmtime_cli_flags::RecordOptions>::to_options
Unexecuted instantiation: <wasmtime_cli_flags::CodegenOptions>::to_options
Unexecuted instantiation: <wasmtime_cli_flags::DebugOptions>::to_options
153
        }
154
    };
155
}
156
157
/// Parser registered with clap which handles parsing the `...` in `-O ...`.
158
#[derive(Clone, Debug, PartialEq)]
159
pub struct CommaSeparated<T>(pub Vec<T>);
160
161
impl<T> ValueParserFactory for CommaSeparated<T>
162
where
163
    T: WasmtimeOption,
164
{
165
    type Parser = CommaSeparatedParser<T>;
166
167
0
    fn value_parser() -> CommaSeparatedParser<T> {
168
0
        CommaSeparatedParser(marker::PhantomData)
169
0
    }
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparated<wasmtime_cli_flags::Wasi> as clap_builder::builder::value_parser::ValueParserFactory>::value_parser
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparated<wasmtime_cli_flags::Wasm> as clap_builder::builder::value_parser::ValueParserFactory>::value_parser
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparated<wasmtime_cli_flags::Debug> as clap_builder::builder::value_parser::ValueParserFactory>::value_parser
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparated<wasmtime_cli_flags::Record> as clap_builder::builder::value_parser::ValueParserFactory>::value_parser
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparated<wasmtime_cli_flags::Codegen> as clap_builder::builder::value_parser::ValueParserFactory>::value_parser
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparated<wasmtime_cli_flags::Optimize> as clap_builder::builder::value_parser::ValueParserFactory>::value_parser
170
}
171
172
#[derive(Clone)]
173
pub struct CommaSeparatedParser<T>(marker::PhantomData<T>);
174
175
impl<T> TypedValueParser for CommaSeparatedParser<T>
176
where
177
    T: WasmtimeOption,
178
{
179
    type Value = CommaSeparated<T>;
180
181
0
    fn parse_ref(
182
0
        &self,
183
0
        cmd: &clap::Command,
184
0
        arg: Option<&clap::Arg>,
185
0
        value: &std::ffi::OsStr,
186
0
    ) -> Result<Self::Value, Error> {
187
0
        let val = StringValueParser::new().parse_ref(cmd, arg, value)?;
188
189
0
        let options = T::OPTIONS;
190
0
        let arg = arg.expect("should always have an argument");
191
0
        let arg_long = arg.get_long().expect("should have a long name specified");
192
0
        let arg_short = arg.get_short().expect("should have a short name specified");
193
194
        // Handle `-O help` which dumps all the `-O` options, their messages,
195
        // and then exits.
196
0
        if val == "help" {
197
0
            let mut max = 0;
198
0
            for d in options {
199
0
                max = max.max(d.name.display_string().len() + d.val_help.len());
200
0
            }
201
0
            println!("Available {arg_long} options:\n");
202
0
            for d in options {
203
0
                print!(
204
                    "  -{arg_short} {:>1$}",
205
0
                    d.name.display_string(),
206
0
                    max - d.val_help.len()
207
                );
208
0
                print!("{}", d.val_help);
209
0
                print!(" --");
210
0
                if val == "help" {
211
0
                    for line in d.docs.lines().map(|s| s.trim()) {
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Wasi> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#0}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Wasm> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#0}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Debug> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#0}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Record> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#0}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Codegen> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#0}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Optimize> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#0}
212
0
                        if line.is_empty() {
213
0
                            break;
214
0
                        }
215
0
                        print!(" {line}");
216
                    }
217
0
                    println!();
218
                } else {
219
0
                    println!();
220
0
                    for line in d.docs.lines().map(|s| s.trim()) {
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Wasi> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#1}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Wasm> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#1}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Debug> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#1}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Record> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#1}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Codegen> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#1}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Optimize> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#1}
221
0
                        let line = line.trim();
222
0
                        println!("        {line}");
223
0
                    }
224
                }
225
            }
226
0
            println!("\npass `-{arg_short} help-long` to see longer-form explanations");
227
0
            std::process::exit(0);
228
0
        }
229
0
        if val == "help-long" {
230
0
            println!("Available {arg_long} options:\n");
231
0
            for d in options {
232
0
                println!(
233
                    "  -{arg_short} {}{} --",
234
0
                    d.name.display_string(),
235
                    d.val_help
236
                );
237
0
                println!();
238
0
                for line in d.docs.lines().map(|s| s.trim()) {
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Wasi> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#2}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Wasm> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#2}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Debug> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#2}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Record> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#2}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Codegen> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#2}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Optimize> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#2}
239
0
                    let line = line.trim();
240
0
                    println!("        {line}");
241
0
                }
242
            }
243
0
            std::process::exit(0);
244
0
        }
245
246
0
        let mut result = Vec::new();
247
0
        for val in val.split(',') {
248
            // Split `k=v` into `k` and `v` where `v` is optional
249
0
            let mut iter = val.splitn(2, '=');
250
0
            let key = iter.next().unwrap();
251
0
            let key_val = iter.next();
252
253
            // Find `key` within `T::OPTIONS`
254
0
            let option = options
255
0
                .iter()
256
0
                .filter_map(|d| match d.name {
257
0
                    OptName::Name(s) => {
258
0
                        let s = s.replace('_', "-");
259
0
                        if s == key { Some((d, s)) } else { None }
260
                    }
261
0
                    OptName::Prefix(s) => {
262
0
                        let name = key.strip_prefix(s)?.strip_prefix("-")?;
263
0
                        Some((d, name.to_string()))
264
                    }
265
0
                })
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Wasi> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#3}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Wasm> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#3}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Debug> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#3}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Record> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#3}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Codegen> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#3}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Optimize> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#3}
266
0
                .next();
267
268
0
            let (desc, key) = match option {
269
0
                Some(pair) => pair,
270
                None => {
271
0
                    let err = Error::raw(
272
0
                        ErrorKind::InvalidValue,
273
0
                        format!("unknown -{arg_short} / --{arg_long} option: {key}\n"),
274
                    );
275
0
                    return Err(err.with_cmd(cmd));
276
                }
277
            };
278
279
0
            result.push((desc.parse)(&key, key_val).map_err(|e| {
280
0
                Error::raw(
281
0
                    ErrorKind::InvalidValue,
282
0
                    format!("failed to parse -{arg_short} option `{val}`: {e:?}\n"),
283
                )
284
0
                .with_cmd(cmd)
285
0
            })?)
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Wasi> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#4}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Wasm> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#4}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Debug> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#4}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Record> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#4}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Codegen> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#4}
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Optimize> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref::{closure#4}
286
        }
287
288
0
        Ok(CommaSeparated(result))
289
0
    }
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Wasi> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Wasm> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Debug> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Record> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Codegen> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref
Unexecuted instantiation: <wasmtime_cli_flags::opt::CommaSeparatedParser<wasmtime_cli_flags::Optimize> as clap_builder::builder::value_parser::TypedValueParser>::parse_ref
290
}
291
292
/// Helper trait used by `CommaSeparated` which contains a list of all options
293
/// supported by the option group.
294
pub trait WasmtimeOption: Sized + Send + Sync + Clone + 'static {
295
    const OPTIONS: &'static [OptionDesc<Self>];
296
}
297
298
pub struct OptionDesc<T> {
299
    pub name: OptName,
300
    pub docs: &'static str,
301
    pub parse: fn(&str, Option<&str>) -> Result<T>,
302
    pub val_help: &'static str,
303
}
304
305
pub enum OptName {
306
    /// A named option. Note that the `str` here uses `_` instead of `-` because
307
    /// it's derived from Rust syntax.
308
    Name(&'static str),
309
310
    /// A prefixed option which strips the specified `name`, then `-`.
311
    Prefix(&'static str),
312
}
313
314
impl OptName {
315
0
    fn display_string(&self) -> String {
316
0
        match self {
317
0
            OptName::Name(s) => s.replace('_', "-"),
318
0
            OptName::Prefix(s) => format!("{s}-<KEY>"),
319
        }
320
0
    }
321
}
322
323
/// A helper trait for all types of options that can be parsed. This is what
324
/// actually parses the `=val` in `key=val`
325
pub trait WasmtimeOptionValue: Sized {
326
    /// Help text for the value to be specified.
327
    const VAL_HELP: &'static str;
328
329
    /// Parses the provided value, if given, returning an error on failure.
330
    fn parse(val: Option<&str>) -> Result<Self>;
331
332
    /// Write the value to `f` that would parse to `self`.
333
    fn display(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
334
}
335
336
impl WasmtimeOptionValue for String {
337
    const VAL_HELP: &'static str = "=val";
338
0
    fn parse(val: Option<&str>) -> Result<Self> {
339
0
        match val {
340
0
            Some(val) => Ok(val.to_string()),
341
0
            None => bail!("value must be specified with `key=val` syntax"),
342
        }
343
0
    }
344
345
0
    fn display(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
346
0
        f.write_str(self)
347
0
    }
348
}
349
350
impl WasmtimeOptionValue for PathBuf {
351
    const VAL_HELP: &'static str = "=path";
352
0
    fn parse(val: Option<&str>) -> Result<Self> {
353
0
        match val {
354
0
            Some(val) => Ok(PathBuf::from_str(val)?),
355
0
            None => bail!("value must be specified with key=val syntax"),
356
        }
357
0
    }
358
359
0
    fn display(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
360
0
        write!(f, "{self:?}")
361
0
    }
362
}
363
364
impl WasmtimeOptionValue for u32 {
365
    const VAL_HELP: &'static str = "=N";
366
0
    fn parse(val: Option<&str>) -> Result<Self> {
367
0
        let val = String::parse(val)?.replace(IGNORED_NUMBER_CHARS, "");
368
0
        match val.strip_prefix("0x") {
369
0
            Some(hex) => Ok(u32::from_str_radix(hex, 16)?),
370
0
            None => Ok(val.parse()?),
371
        }
372
0
    }
373
374
0
    fn display(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
375
0
        write!(f, "{self}")
376
0
    }
377
}
378
379
impl WasmtimeOptionValue for NonZeroU32 {
380
    const VAL_HELP: &'static str = "=N";
381
382
0
    fn parse(val: Option<&str>) -> Result<Self> {
383
0
        let n = <u32 as WasmtimeOptionValue>::parse(val)?;
384
0
        NonZeroU32::new(n).ok_or_else(|| format_err!("value must be non-zero"))
385
0
    }
386
387
0
    fn display(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
388
0
        write!(f, "{self}")
389
0
    }
390
}
391
392
impl WasmtimeOptionValue for u64 {
393
    const VAL_HELP: &'static str = "=N";
394
0
    fn parse(val: Option<&str>) -> Result<Self> {
395
0
        let val = String::parse(val)?.replace(IGNORED_NUMBER_CHARS, "");
396
0
        match val.strip_prefix("0x") {
397
0
            Some(hex) => Ok(u64::from_str_radix(hex, 16)?),
398
0
            None => Ok(val.parse()?),
399
        }
400
0
    }
401
402
0
    fn display(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
403
0
        write!(f, "{self}")
404
0
    }
405
}
406
407
impl WasmtimeOptionValue for usize {
408
    const VAL_HELP: &'static str = "=N";
409
0
    fn parse(val: Option<&str>) -> Result<Self> {
410
0
        let val = String::parse(val)?.replace(IGNORED_NUMBER_CHARS, "");
411
0
        match val.strip_prefix("0x") {
412
0
            Some(hex) => Ok(usize::from_str_radix(hex, 16)?),
413
0
            None => Ok(val.parse()?),
414
        }
415
0
    }
416
417
0
    fn display(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
418
0
        write!(f, "{self}")
419
0
    }
420
}
421
422
impl WasmtimeOptionValue for bool {
423
    const VAL_HELP: &'static str = "[=y|n]";
424
0
    fn parse(val: Option<&str>) -> Result<Self> {
425
0
        match val {
426
0
            None | Some("y") | Some("yes") | Some("true") => Ok(true),
427
0
            Some("n") | Some("no") | Some("false") => Ok(false),
428
0
            Some(s) => bail!("unknown boolean flag `{s}`, only yes,no,<nothing> accepted"),
429
        }
430
0
    }
431
432
0
    fn display(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
433
0
        if *self {
434
0
            f.write_str("y")
435
        } else {
436
0
            f.write_str("n")
437
        }
438
0
    }
439
}
440
441
impl WasmtimeOptionValue for Duration {
442
    const VAL_HELP: &'static str = "=N|Ns|Nms|..";
443
0
    fn parse(val: Option<&str>) -> Result<Duration> {
444
0
        let s = String::parse(val)?;
445
        // assume an integer without a unit specified is a number of seconds ...
446
0
        if let Ok(val) = s.parse() {
447
0
            return Ok(Duration::from_secs(val));
448
0
        }
449
450
0
        if let Some(num) = s.strip_suffix("s") {
451
0
            if let Ok(val) = num.parse() {
452
0
                return Ok(Duration::from_secs(val));
453
0
            }
454
0
        }
455
0
        if let Some(num) = s.strip_suffix("ms") {
456
0
            if let Ok(val) = num.parse() {
457
0
                return Ok(Duration::from_millis(val));
458
0
            }
459
0
        }
460
0
        if let Some(num) = s.strip_suffix("us").or(s.strip_suffix("μs")) {
461
0
            if let Ok(val) = num.parse() {
462
0
                return Ok(Duration::from_micros(val));
463
0
            }
464
0
        }
465
0
        if let Some(num) = s.strip_suffix("ns") {
466
0
            if let Ok(val) = num.parse() {
467
0
                return Ok(Duration::from_nanos(val));
468
0
            }
469
0
        }
470
471
0
        bail!("failed to parse duration: {s}")
472
0
    }
473
474
0
    fn display(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
475
0
        let subsec = self.subsec_nanos();
476
0
        if subsec == 0 {
477
0
            write!(f, "{}s", self.as_secs())
478
0
        } else if subsec % 1_000 == 0 {
479
0
            write!(f, "{}μs", self.as_micros())
480
0
        } else if subsec % 1_000_000 == 0 {
481
0
            write!(f, "{}ms", self.as_millis())
482
        } else {
483
0
            write!(f, "{}ns", self.as_nanos())
484
        }
485
0
    }
486
}
487
488
impl WasmtimeOptionValue for wasmtime::OptLevel {
489
    const VAL_HELP: &'static str = "=0|1|2|s";
490
0
    fn parse(val: Option<&str>) -> Result<Self> {
491
0
        match String::parse(val)?.as_str() {
492
0
            "0" => Ok(wasmtime::OptLevel::None),
493
0
            "1" => Ok(wasmtime::OptLevel::Speed),
494
0
            "2" => Ok(wasmtime::OptLevel::Speed),
495
0
            "s" => Ok(wasmtime::OptLevel::SpeedAndSize),
496
0
            other => bail!("unknown optimization level `{other}`, only 0,1,2,s accepted"),
497
        }
498
0
    }
499
500
0
    fn display(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
501
0
        match *self {
502
0
            wasmtime::OptLevel::None => f.write_str("0"),
503
0
            wasmtime::OptLevel::Speed => f.write_str("2"),
504
0
            wasmtime::OptLevel::SpeedAndSize => f.write_str("s"),
505
0
            _ => unreachable!(),
506
        }
507
0
    }
508
}
509
510
impl WasmtimeOptionValue for wasmtime::RegallocAlgorithm {
511
    const VAL_HELP: &'static str = "=backtracking|single-pass";
512
0
    fn parse(val: Option<&str>) -> Result<Self> {
513
0
        match String::parse(val)?.as_str() {
514
0
            "backtracking" => Ok(wasmtime::RegallocAlgorithm::Backtracking),
515
0
            "single-pass" => Ok(wasmtime::RegallocAlgorithm::SinglePass),
516
0
            other => {
517
0
                bail!("unknown regalloc algorithm`{other}`, only backtracking,single-pass accepted")
518
            }
519
        }
520
0
    }
521
522
0
    fn display(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
523
0
        match *self {
524
0
            wasmtime::RegallocAlgorithm::Backtracking => f.write_str("backtracking"),
525
0
            wasmtime::RegallocAlgorithm::SinglePass => f.write_str("single-pass"),
526
0
            _ => unreachable!(),
527
        }
528
0
    }
529
}
530
531
impl WasmtimeOptionValue for wasmtime::Strategy {
532
    const VAL_HELP: &'static str = "=winch|cranelift";
533
0
    fn parse(val: Option<&str>) -> Result<Self> {
534
0
        match String::parse(val)?.as_str() {
535
0
            "cranelift" => Ok(wasmtime::Strategy::Cranelift),
536
0
            "winch" => Ok(wasmtime::Strategy::Winch),
537
0
            other => bail!("unknown compiler `{other}` only `cranelift` and `winch` accepted",),
538
        }
539
0
    }
540
541
0
    fn display(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
542
0
        match *self {
543
0
            wasmtime::Strategy::Cranelift => f.write_str("cranelift"),
544
0
            wasmtime::Strategy::Winch => f.write_str("winch"),
545
0
            _ => unreachable!(),
546
        }
547
0
    }
548
}
549
550
impl WasmtimeOptionValue for wasmtime::Collector {
551
    const VAL_HELP: &'static str = "=drc|null|copying";
552
0
    fn parse(val: Option<&str>) -> Result<Self> {
553
0
        match String::parse(val)?.as_str() {
554
0
            "drc" => Ok(wasmtime::Collector::DeferredReferenceCounting),
555
0
            "null" => Ok(wasmtime::Collector::Null),
556
0
            "copying" => Ok(wasmtime::Collector::Copying),
557
0
            other => {
558
0
                bail!("unknown collector `{other}` only `drc`, `null`, and `copying` accepted",)
559
            }
560
        }
561
0
    }
562
563
0
    fn display(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
564
0
        match *self {
565
0
            wasmtime::Collector::DeferredReferenceCounting => f.write_str("drc"),
566
0
            wasmtime::Collector::Null => f.write_str("null"),
567
0
            wasmtime::Collector::Copying => f.write_str("copying"),
568
0
            _ => unreachable!(),
569
        }
570
0
    }
571
}
572
573
impl WasmtimeOptionValue for wasmtime::Enabled {
574
    const VAL_HELP: &'static str = "[=y|n|auto]";
575
0
    fn parse(val: Option<&str>) -> Result<Self> {
576
0
        match val {
577
0
            None | Some("y") | Some("yes") | Some("true") => Ok(wasmtime::Enabled::Yes),
578
0
            Some("n") | Some("no") | Some("false") => Ok(wasmtime::Enabled::No),
579
0
            Some("auto") => Ok(wasmtime::Enabled::Auto),
580
0
            Some(s) => bail!("unknown flag `{s}`, only yes,no,auto,<nothing> accepted"),
581
        }
582
0
    }
583
584
0
    fn display(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
585
0
        match *self {
586
0
            wasmtime::Enabled::Yes => f.write_str("y"),
587
0
            wasmtime::Enabled::No => f.write_str("n"),
588
0
            wasmtime::Enabled::Auto => f.write_str("auto"),
589
        }
590
0
    }
591
}
592
593
impl WasmtimeOptionValue for wasmtime::Inlining {
594
    const VAL_HELP: &'static str = "[=y|n|gc|inter-module|intrinsics]";
595
0
    fn parse(val: Option<&str>) -> Result<Self> {
596
0
        match val {
597
0
            None => Ok(wasmtime::Inlining::Yes),
598
0
            Some(val) => val.parse(),
599
        }
600
0
    }
601
602
0
    fn display(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
603
0
        write!(f, "{self}")
604
0
    }
605
}
606
607
impl WasmtimeOptionValue for WasiNnGraph {
608
    const VAL_HELP: &'static str = "=<format>::<dir>";
609
0
    fn parse(val: Option<&str>) -> Result<Self> {
610
0
        let val = String::parse(val)?;
611
0
        let mut parts = val.splitn(2, "::");
612
        Ok(WasiNnGraph {
613
0
            format: parts.next().unwrap().to_string(),
614
0
            dir: match parts.next() {
615
0
                Some(part) => part.into(),
616
0
                None => bail!("graph does not contain `::` separator for directory"),
617
            },
618
        })
619
0
    }
620
621
0
    fn display(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
622
0
        write!(f, "{}::{}", self.format, self.dir)
623
0
    }
624
}
625
626
impl WasmtimeOptionValue for KeyValuePair {
627
    const VAL_HELP: &'static str = "=<name>=<val>";
628
0
    fn parse(val: Option<&str>) -> Result<Self> {
629
0
        let val = String::parse(val)?;
630
0
        let mut parts = val.splitn(2, "=");
631
        Ok(KeyValuePair {
632
0
            key: parts.next().unwrap().to_string(),
633
0
            value: match parts.next() {
634
0
                Some(part) => part.into(),
635
0
                None => "".to_string(),
636
            },
637
        })
638
0
    }
639
640
0
    fn display(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
641
0
        f.write_str(&self.key)?;
642
0
        if !self.value.is_empty() {
643
0
            f.write_str("=")?;
644
0
            f.write_str(&self.value)?;
645
0
        }
646
0
        Ok(())
647
0
    }
648
}
649
650
pub trait OptionContainer<T> {
651
    fn push(&mut self, val: T);
652
    fn get<'a>(&'a self) -> impl Iterator<Item = &'a T>
653
    where
654
        T: 'a;
655
}
656
657
impl<T> OptionContainer<T> for Option<T> {
658
0
    fn push(&mut self, val: T) {
659
0
        *self = Some(val);
660
0
    }
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u32>> as wasmtime_cli_flags::opt::OptionContainer<core::num::nonzero::NonZero<u32>>>::push
Unexecuted instantiation: <core::option::Option<core::time::Duration> as wasmtime_cli_flags::opt::OptionContainer<core::time::Duration>>::push
Unexecuted instantiation: <core::option::Option<wasmtime::config::RegallocAlgorithm> as wasmtime_cli_flags::opt::OptionContainer<wasmtime::config::RegallocAlgorithm>>::push
Unexecuted instantiation: <core::option::Option<wasmtime::config::Enabled> as wasmtime_cli_flags::opt::OptionContainer<wasmtime::config::Enabled>>::push
Unexecuted instantiation: <core::option::Option<wasmtime::config::OptLevel> as wasmtime_cli_flags::opt::OptionContainer<wasmtime::config::OptLevel>>::push
Unexecuted instantiation: <core::option::Option<wasmtime::config::Strategy> as wasmtime_cli_flags::opt::OptionContainer<wasmtime::config::Strategy>>::push
Unexecuted instantiation: <core::option::Option<wasmtime::config::Collector> as wasmtime_cli_flags::opt::OptionContainer<wasmtime::config::Collector>>::push
Unexecuted instantiation: <core::option::Option<std::path::PathBuf> as wasmtime_cli_flags::opt::OptionContainer<std::path::PathBuf>>::push
Unexecuted instantiation: <core::option::Option<alloc::string::String> as wasmtime_cli_flags::opt::OptionContainer<alloc::string::String>>::push
Unexecuted instantiation: <core::option::Option<wasmtime_environ::tunables::Inlining> as wasmtime_cli_flags::opt::OptionContainer<wasmtime_environ::tunables::Inlining>>::push
Unexecuted instantiation: <core::option::Option<bool> as wasmtime_cli_flags::opt::OptionContainer<bool>>::push
Unexecuted instantiation: <core::option::Option<usize> as wasmtime_cli_flags::opt::OptionContainer<usize>>::push
Unexecuted instantiation: <core::option::Option<u32> as wasmtime_cli_flags::opt::OptionContainer<u32>>::push
Unexecuted instantiation: <core::option::Option<u64> as wasmtime_cli_flags::opt::OptionContainer<u64>>::push
661
0
    fn get<'a>(&'a self) -> impl Iterator<Item = &'a T>
662
0
    where
663
0
        T: 'a,
664
    {
665
0
        self.iter()
666
0
    }
Unexecuted instantiation: <core::option::Option<core::num::nonzero::NonZero<u32>> as wasmtime_cli_flags::opt::OptionContainer<core::num::nonzero::NonZero<u32>>>::get
Unexecuted instantiation: <core::option::Option<core::time::Duration> as wasmtime_cli_flags::opt::OptionContainer<core::time::Duration>>::get
Unexecuted instantiation: <core::option::Option<wasmtime::config::RegallocAlgorithm> as wasmtime_cli_flags::opt::OptionContainer<wasmtime::config::RegallocAlgorithm>>::get
Unexecuted instantiation: <core::option::Option<wasmtime::config::Enabled> as wasmtime_cli_flags::opt::OptionContainer<wasmtime::config::Enabled>>::get
Unexecuted instantiation: <core::option::Option<wasmtime::config::OptLevel> as wasmtime_cli_flags::opt::OptionContainer<wasmtime::config::OptLevel>>::get
Unexecuted instantiation: <core::option::Option<wasmtime::config::Strategy> as wasmtime_cli_flags::opt::OptionContainer<wasmtime::config::Strategy>>::get
Unexecuted instantiation: <core::option::Option<wasmtime::config::Collector> as wasmtime_cli_flags::opt::OptionContainer<wasmtime::config::Collector>>::get
Unexecuted instantiation: <core::option::Option<std::path::PathBuf> as wasmtime_cli_flags::opt::OptionContainer<std::path::PathBuf>>::get
Unexecuted instantiation: <core::option::Option<alloc::string::String> as wasmtime_cli_flags::opt::OptionContainer<alloc::string::String>>::get
Unexecuted instantiation: <core::option::Option<wasmtime_environ::tunables::Inlining> as wasmtime_cli_flags::opt::OptionContainer<wasmtime_environ::tunables::Inlining>>::get
Unexecuted instantiation: <core::option::Option<bool> as wasmtime_cli_flags::opt::OptionContainer<bool>>::get
Unexecuted instantiation: <core::option::Option<usize> as wasmtime_cli_flags::opt::OptionContainer<usize>>::get
Unexecuted instantiation: <core::option::Option<u32> as wasmtime_cli_flags::opt::OptionContainer<u32>>::get
Unexecuted instantiation: <core::option::Option<u64> as wasmtime_cli_flags::opt::OptionContainer<u64>>::get
667
}
668
669
impl<T> OptionContainer<T> for Vec<T> {
670
0
    fn push(&mut self, val: T) {
671
0
        Vec::push(self, val);
672
0
    }
Unexecuted instantiation: <alloc::vec::Vec<wasmtime_cli_flags::WasiNnGraph> as wasmtime_cli_flags::opt::OptionContainer<wasmtime_cli_flags::WasiNnGraph>>::push
Unexecuted instantiation: <alloc::vec::Vec<wasmtime_cli_flags::KeyValuePair> as wasmtime_cli_flags::opt::OptionContainer<wasmtime_cli_flags::KeyValuePair>>::push
Unexecuted instantiation: <alloc::vec::Vec<alloc::string::String> as wasmtime_cli_flags::opt::OptionContainer<alloc::string::String>>::push
673
0
    fn get<'a>(&'a self) -> impl Iterator<Item = &'a T>
674
0
    where
675
0
        T: 'a,
676
    {
677
0
        self.iter()
678
0
    }
Unexecuted instantiation: <alloc::vec::Vec<wasmtime_cli_flags::WasiNnGraph> as wasmtime_cli_flags::opt::OptionContainer<wasmtime_cli_flags::WasiNnGraph>>::get
Unexecuted instantiation: <alloc::vec::Vec<wasmtime_cli_flags::KeyValuePair> as wasmtime_cli_flags::opt::OptionContainer<wasmtime_cli_flags::KeyValuePair>>::get
Unexecuted instantiation: <alloc::vec::Vec<alloc::string::String> as wasmtime_cli_flags::opt::OptionContainer<alloc::string::String>>::get
679
}
680
681
// Used to parse toml values into string so that we can reuse the `WasmtimeOptionValue::parse`
682
// for parsing toml values the same way we parse command line values.
683
//
684
// Used for wasmtime::Strategy, wasmtime::Collector, wasmtime::OptLevel, wasmtime::RegallocAlgorithm
685
struct ToStringVisitor {}
686
687
impl<'de> Visitor<'de> for ToStringVisitor {
688
    type Value = String;
689
690
0
    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
691
0
        write!(formatter, "&str, u64, or i64")
692
0
    }
693
694
0
    fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
695
0
    where
696
0
        E: de::Error,
697
    {
698
0
        Ok(s.to_owned())
699
0
    }
700
701
0
    fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
702
0
    where
703
0
        E: de::Error,
704
    {
705
0
        Ok(v.to_string())
706
0
    }
707
708
0
    fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
709
0
    where
710
0
        E: de::Error,
711
    {
712
0
        Ok(v.to_string())
713
0
    }
714
}
715
716
// Deserializer that uses the `WasmtimeOptionValue::parse` to parse toml values
717
0
pub(crate) fn cli_parse_wrapper<'de, D, T>(deserializer: D) -> Result<Option<T>, D::Error>
718
0
where
719
0
    T: WasmtimeOptionValue,
720
0
    D: serde::Deserializer<'de>,
721
{
722
0
    let to_string_visitor = ToStringVisitor {};
723
0
    let str = deserializer.deserialize_any(to_string_visitor)?;
724
725
0
    T::parse(Some(&str))
726
0
        .map(Some)
727
0
        .map_err(serde::de::Error::custom)
728
0
}
Unexecuted instantiation: wasmtime_cli_flags::opt::cli_parse_wrapper::<serde_core::de::value::UsizeDeserializer<toml::de::error::Error>, wasmtime::config::RegallocAlgorithm>
Unexecuted instantiation: wasmtime_cli_flags::opt::cli_parse_wrapper::<serde_core::de::value::UsizeDeserializer<toml::de::error::Error>, wasmtime::config::Enabled>
Unexecuted instantiation: wasmtime_cli_flags::opt::cli_parse_wrapper::<serde_core::de::value::UsizeDeserializer<toml::de::error::Error>, wasmtime::config::OptLevel>
Unexecuted instantiation: wasmtime_cli_flags::opt::cli_parse_wrapper::<serde_core::de::value::UsizeDeserializer<toml::de::error::Error>, wasmtime::config::Strategy>
Unexecuted instantiation: wasmtime_cli_flags::opt::cli_parse_wrapper::<serde_core::de::value::UsizeDeserializer<toml::de::error::Error>, wasmtime::config::Collector>
Unexecuted instantiation: wasmtime_cli_flags::opt::cli_parse_wrapper::<serde_core::de::value::UsizeDeserializer<toml::de::error::Error>, wasmtime_environ::tunables::Inlining>
Unexecuted instantiation: wasmtime_cli_flags::opt::cli_parse_wrapper::<serde_core::de::value::StringDeserializer<toml::de::error::Error>, wasmtime::config::RegallocAlgorithm>
Unexecuted instantiation: wasmtime_cli_flags::opt::cli_parse_wrapper::<serde_core::de::value::StringDeserializer<toml::de::error::Error>, wasmtime::config::Enabled>
Unexecuted instantiation: wasmtime_cli_flags::opt::cli_parse_wrapper::<serde_core::de::value::StringDeserializer<toml::de::error::Error>, wasmtime::config::OptLevel>
Unexecuted instantiation: wasmtime_cli_flags::opt::cli_parse_wrapper::<serde_core::de::value::StringDeserializer<toml::de::error::Error>, wasmtime::config::Strategy>
Unexecuted instantiation: wasmtime_cli_flags::opt::cli_parse_wrapper::<serde_core::de::value::StringDeserializer<toml::de::error::Error>, wasmtime::config::Collector>
Unexecuted instantiation: wasmtime_cli_flags::opt::cli_parse_wrapper::<serde_core::de::value::StringDeserializer<toml::de::error::Error>, wasmtime_environ::tunables::Inlining>
Unexecuted instantiation: wasmtime_cli_flags::opt::cli_parse_wrapper::<toml::de::deserializer::value::ValueDeserializer, wasmtime::config::RegallocAlgorithm>
Unexecuted instantiation: wasmtime_cli_flags::opt::cli_parse_wrapper::<toml::de::deserializer::value::ValueDeserializer, wasmtime::config::Enabled>
Unexecuted instantiation: wasmtime_cli_flags::opt::cli_parse_wrapper::<toml::de::deserializer::value::ValueDeserializer, wasmtime::config::OptLevel>
Unexecuted instantiation: wasmtime_cli_flags::opt::cli_parse_wrapper::<toml::de::deserializer::value::ValueDeserializer, wasmtime::config::Strategy>
Unexecuted instantiation: wasmtime_cli_flags::opt::cli_parse_wrapper::<toml::de::deserializer::value::ValueDeserializer, wasmtime::config::Collector>
Unexecuted instantiation: wasmtime_cli_flags::opt::cli_parse_wrapper::<toml::de::deserializer::value::ValueDeserializer, wasmtime_environ::tunables::Inlining>
729
730
#[cfg(test)]
731
mod tests {
732
    use super::WasmtimeOptionValue;
733
734
    #[test]
735
    fn numbers_with_underscores() {
736
        assert!(<u32 as WasmtimeOptionValue>::parse(Some("123")).is_ok_and(|v| v == 123));
737
        assert!(<u32 as WasmtimeOptionValue>::parse(Some("1_2_3")).is_ok_and(|v| v == 123));
738
    }
739
}