use arbitrary::{Result, Unstructured};
use wit_parser::{Resolve, ResolveErrorKind};
mod config;
pub use self::config::Config;
mod generate;
pub fn smith(config: &Config, u: &mut Unstructured<'_>) -> Result<Vec<u8>> {
let pkgs = generate::Generator::new(config.clone()).generate(u)?;
let mut resolve = Resolve::default();
resolve.all_features = true;
let mut last = None;
for pkg in pkgs {
log::trace!("appending package {:?}", pkg.name);
let group = pkg.sources.parse().unwrap();
let id = match resolve.push_group(group) {
Ok(id) => id,
Err(e) => match e.kind() {
ResolveErrorKind::InvalidTransitiveDependency { .. } => {
return Err(arbitrary::Error::IncorrectFormat);
}
ResolveErrorKind::ItemShadowing { .. }
| ResolveErrorKind::StabilityMismatch { .. } => {
log::error!("{e}");
return Err(arbitrary::Error::IncorrectFormat);
}
_ => {
panic!("bad wit parse: {e:?}")
}
},
};
last = Some(id);
}
let pkg = last.unwrap();
let wasm = wit_component::encode(&resolve, pkg).expect("failed to encode WIT document");
if let Err(e) = wasmparser::Validator::new_with_features(wasmparser::WasmFeatures::all())
.validate_all(&wasm)
{
if e.to_string()
.contains("`stream<char>` is not valid at this time")
{
return Err(arbitrary::Error::IncorrectFormat);
}
}
Ok(wasm)
}