/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 | | } |