1use std::path::{Path, PathBuf};
5use std::{fs, io, str};
6
7use chaste_types::Chastefile;
8use yarn_lock_parser as yarn;
9
10pub use crate::error::{Error, Result};
11
12#[cfg(feature = "berry")]
13mod berry;
14#[cfg(feature = "classic")]
15mod classic;
16mod error;
17#[cfg(test)]
18mod tests;
19
20pub static LOCKFILE_NAME: &str = "yarn.lock";
21
22pub fn parse<P>(root_dir: P) -> Result<Chastefile>
23where
24 P: AsRef<Path>,
25{
26 let root_dir = root_dir.as_ref();
27
28 let lockfile_contents = fs::read_to_string(root_dir.join(LOCKFILE_NAME))?;
29 parse_real(&lockfile_contents, root_dir, &fs::read_to_string)
30}
31
32fn parse_real<FG>(lockfile_contents: &str, root_dir: &Path, file_getter: &FG) -> Result<Chastefile>
33where
34 FG: Fn(PathBuf) -> Result<String, io::Error>,
35{
36 let yarn_lock: yarn::Lockfile = yarn::parse_str(&lockfile_contents)?;
37 match yarn_lock.version {
38 #[cfg(feature = "classic")]
39 1 => classic::resolve(yarn_lock, root_dir, file_getter),
40 #[cfg(feature = "berry")]
41 2..=8 => berry::resolve(yarn_lock, root_dir, file_getter),
42 _ => Err(Error::UnknownLockfileVersion(yarn_lock.version)),
43 }
44}
45
46#[cfg(feature = "fuzzing")]
47pub fn parse_arbitrary<FG>(
48 lockfile_contents: &str,
49 root_dir: &Path,
50 file_getter: &FG,
51) -> Result<Chastefile>
52where
53 FG: Fn(PathBuf) -> Result<String, io::Error>,
54{
55 parse_real(lockfile_contents, root_dir, file_getter)
56}