Parse `{ "imports": {...}, "extends": "..." }`. Both optional; unknown keys skipped for forward compat; numbers, arrays, bools rejected. */
(bytes: &[u8])
| 13 | |
| 14 | /* Parse `{ "imports": {...}, "extends": "..." }`. Both optional; unknown keys skipped for forward compat; numbers, arrays, bools rejected. */ |
| 15 | pub fn parse_manifest(bytes: &[u8]) -> Result<Manifest, String> { |
| 16 | let src = core::str::from_utf8(bytes).map_err(|_| s!("packages.json is not valid UTF-8"))?; |
| 17 | let mut p = Reader { src: src.as_bytes(), pos: 0 }; |
| 18 | let mut m = Manifest { imports: Vec::new(), extends: None }; |
| 19 | |
| 20 | p.skip_ws(); |
| 21 | p.expect(b'{', "packages.json must be a JSON object")?; |
| 22 | p.skip_ws(); |
| 23 | if p.peek() == Some(b'}') { return Ok(m); } |
| 24 | |
| 25 | loop { |
| 26 | p.skip_ws(); |
| 27 | let key = p.read_string()?; |
| 28 | p.skip_ws(); |
| 29 | p.expect(b':', "expected ':' after key in packages.json")?; |
| 30 | p.skip_ws(); |
| 31 | match key.as_str() { |
| 32 | "imports" => p.read_imports_into(&mut m.imports)?, |
| 33 | "extends" => m.extends = Some(p.read_string()?), |
| 34 | _ => p.skip_value()?, |
| 35 | } |
| 36 | p.skip_ws(); |
| 37 | match p.peek() { |
| 38 | Some(b',') => { p.pos += 1; continue; } |
| 39 | Some(b'}') => return Ok(m), |
| 40 | _ => return Err(s!("expected ',' or '}' in packages.json")), |
| 41 | } |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | /* Yield the directory of `start` and every parent, in order. Each ends in '/' or is "" (topmost). */ |
| 46 | pub fn walk_up_dirs(start: &str) -> impl Iterator<Item = String> + '_ { |
no test coverage detected