1use std::fs;
4use std::path::PathBuf;
5
6use anyhow::{anyhow, bail, Context, Result};
7use console::style;
8use toml;
9
10use crate::manifest::CrateData;
11
12#[derive(Clone, Debug, Deserialize)]
14pub struct Lockfile {
15 package: Vec<Package>,
16}
17
18#[derive(Clone, Debug, Deserialize)]
20struct Package {
21 name: String,
22 version: String,
23}
24
25impl Lockfile {
26 pub fn new(crate_data: &CrateData) -> Result<Lockfile> {
28 let lock_path = get_lockfile_path(crate_data)?;
29 let lockfile = fs::read_to_string(&lock_path)
30 .with_context(|| anyhow!("failed to read: {}", lock_path.display()))?;
31 let lockfile = toml::from_str(&lockfile)
32 .with_context(|| anyhow!("failed to parse: {}", lock_path.display()))?;
33 Ok(lockfile)
34 }
35
36 pub fn wasm_bindgen_version(&self) -> Option<&str> {
38 self.get_package_version("wasm-bindgen")
39 }
40
41 pub fn require_wasm_bindgen(&self) -> Result<&str> {
44 self.wasm_bindgen_version().ok_or_else(|| {
45 anyhow!(
46 "Ensure that you have \"{}\" as a dependency in your Cargo.toml file:\n\
47 [dependencies]\n\
48 wasm-bindgen = \"0.2\"",
49 style("wasm-bindgen").bold().dim(),
50 )
51 })
52 }
53
54 pub fn wasm_bindgen_test_version(&self) -> Option<&str> {
56 self.get_package_version("wasm-bindgen-test")
57 }
58
59 fn get_package_version(&self, package: &str) -> Option<&str> {
60 self.package
61 .iter()
62 .find(|p| p.name == package)
63 .map(|p| &p.version[..])
64 }
65}
66
67fn get_lockfile_path(crate_data: &CrateData) -> Result<PathBuf> {
70 let lockfile_path = crate_data.workspace_root().join("Cargo.lock");
73 if !lockfile_path.is_file() {
74 bail!("Could not find lockfile at {:?}", lockfile_path)
75 } else {
76 Ok(lockfile_path)
77 }
78}