//! # crx-manifest-parser
//!
//! Parse a Chrome / Chromium **Manifest V3** `manifest.json` string into a
//! strongly-typed [`Manifest`] struct exposing the fields an extension
//! security scanner actually cares about:
//!
//! - `name`, `version`, `description`, `manifest_version`
//! - `permissions` and `optional_permissions` (named API tokens)
//! - `host_permissions` (match-patterns granting site access)
//! - `content_scripts` (the script + match list, the biggest cross-origin
//!   exposure surface)
//!
//! The crate is pure Rust, **zero-dependency** (no `serde`, no `serde_json`),
//! `#![forbid(unsafe_code)]`, and carries its own minimal JSON value parser
//! so a manifest can be decoded in any sandboxed or `#[no_std]`-adjacent
//! context without dragging in a JSON library.
//!
//! This is the manifest-decode layer behind the
//! [**zovo.one**](https://zovo.one/) Chrome-extension privacy &amp; security
//! scanner.
//!
//! ## Quick example
//!
//! ```
//! use crx_manifest_parser::Manifest;
//!
//! let json = r#"{
//!     "manifest_version": 3,
//!     "name": "My Extension",
//!     "version": "1.4.2",
//!     "permissions": ["activeTab", "storage"],
//!     "host_permissions": ["https://*.example.com/*"],
//!     "content_scripts": [
//!         {
//!             "matches": ["https://*.example.com/*"],
//!             "js": ["content.js"]
//!         }
//!     ]
//! }"#;
//!
//! let manifest = Manifest::from_json(json).expect("valid manifest");
//! assert_eq!(manifest.name.as_deref(), Some("My Extension"));
//! assert_eq!(manifest.version.as_deref(), Some("1.4.2"));
//! assert_eq!(manifest.manifest_version, Some(3));
//! assert_eq!(manifest.permissions, ["activeTab", "storage"]);
//! assert_eq!(manifest.host_permissions, ["https://*.example.com/*"]);
//! assert_eq!(manifest.content_scripts.len(), 1);
//! ```

#![forbid(unsafe_code)]

mod json;
mod parse;

pub use parse::{ContentScript, Manifest};

// Re-export the minimal JSON value model so downstream callers can inspect a
// raw field without re-parsing.
pub use json::{Json, ParseError};
