1use arbitrary::{Result, Unstructured};
9use wit_parser::{Resolve, ResolveErrorKind};
10
11mod config;
12pub use self::config::Config;
13mod generate;
14
15pub fn smith(config: &Config, u: &mut Unstructured<'_>) -> Result<Vec<u8>> {
20 let pkgs = generate::Generator::new(config.clone()).generate(u)?;
21 let mut resolve = Resolve::default();
22 resolve.all_features = true;
23 let mut last = None;
24 for pkg in pkgs {
25 log::trace!("appending package {:?}", pkg.name);
26 let group = pkg.sources.parse().unwrap();
27 let id = match resolve.push_group(group) {
28 Ok(id) => id,
29 Err(e) => match e.kind() {
30 ResolveErrorKind::InvalidTransitiveDependency { .. } => {
31 return Err(arbitrary::Error::IncorrectFormat);
32 }
33 ResolveErrorKind::ItemShadowing { .. }
34 | ResolveErrorKind::StabilityMismatch { .. } => {
35 log::error!("{e}");
36 return Err(arbitrary::Error::IncorrectFormat);
37 }
38 _ => {
39 panic!("bad wit parse: {e:?}")
40 }
41 },
42 };
43 last = Some(id);
44 }
45 let pkg = last.unwrap();
46
47 let wasm = wit_component::encode(&resolve, pkg).expect("failed to encode WIT document");
48
49 if let Err(e) = wasmparser::Validator::new_with_features(wasmparser::WasmFeatures::all())
52 .validate_all(&wasm)
53 {
54 if e.to_string()
55 .contains("`stream<char>` is not valid at this time")
56 {
57 return Err(arbitrary::Error::IncorrectFormat);
58 }
59 }
60 Ok(wasm)
61}