diff --git a/README.md b/README.md index 6c886e7..fcfecb1 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ valq = "*" ## What's provided The principal macro provided by this crate is `query_value!`. -Also, there is a `Result`-returning variant of `query_value!`, called `query_value_result!`. +There is also a `Result`-returning variant of `query_value!`, called `query_value_reosult!`. ### `query_value!` macro A macro for querying, extracting and converting inner value of semi-structured data. diff --git a/examples/basics.rs b/examples/basics.rs new file mode 100644 index 0000000..2bd9e09 --- /dev/null +++ b/examples/basics.rs @@ -0,0 +1,55 @@ +use serde::Deserialize; +use serde_json::json; +use valq::{query_value, query_value_result}; + +fn main() { + let data = json!({ + "package": { + "name": "valq", + "version": "0.3.0", + "authors": ["jiftechnify"], + "description": "macros for querying semi-structured data with the JavaScript-like syntax", + "keywords": ["macro", "query", "json"] + }, + "dependencies": { + "paste": { "version": "1.0.15" } + }, + "dev-dependencies": { + "serde": { + "version": "1.0.228", + "features": ["derive"] + } + } + }); + + assert_eq!(query_value!(data.package.name -> str).unwrap(), "valq"); + + assert_eq!( + query_value!(data.package.keywords >> (Vec)).unwrap(), + ["macro", "query", "json"], + ); + + let res: valq::Result<&str> = query_value_result!(data.package.readme -> str); + if let Err(valq::Error::ValueNotFoundAtPath(path)) = res { + assert_eq!(path, ".package.readme") + } + else { + unreachable!() + } + + assert_eq!( + query_value!(data.package.readme -> str ?? "README.md"), + "README.md", + ); + + let dep_name = "paste"; + assert_eq!( + query_value!(data.dependencies[dep_name].version -> str).unwrap(), + "1.0.15", + ); + + assert_eq!( + query_value!(data["dev-dependencies"]["serde"].features[0] >> String ?? "none".into()), + "derive".to_string(), + ); +} diff --git a/src/lib.rs b/src/lib.rs index 9aa4cab..bdfc028 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,23 +1,83 @@ -//! # valq -//! `valq` provides macros for querying and extracting an inner value from a structured data **with the JavaScript-like syntax**. +//! `valq` provides macros for querying semi-structured ("JSON-ish") data **with the JavaScript-like syntax**. //! -//! ``` -//! # use serde_json::json; -//! use serde_json::Value; +//! The principal macro provided by this crate is `query_value!`. Read [the `query_value` doc] for detailed usage. +//! There is also a `Result`-returning variant of `query_value!`, called [`query_value_result!`]. +//! +//! [the `query_value` doc]: crate::query_value +//! [`query_value_result!`]: crate::query_value_result +//! +//! ## Example +//! +//! ```rust +//! use serde::Deserialize; +//! use serde_json::{json, Value}; //! use valq::{query_value, query_value_result}; //! -//! // let obj: Value = ...; -//! # let obj = json!({}); -//! let deep_val: Option<&Value> = query_value!(obj.path.to.value.at.deep); -//! let deep_val_res: Result<&Value, valq::Error> = query_value_result!(obj.path.to.value.at.deep); -//! ``` +//! let data = json!({ +//! "package": { +//! "name": "valq", +//! "authors": ["jiftechnify"], +//! "keywords": ["macro", "query", "json"] +//! }, +//! "dependencies": { +//! "paste": { +//! "version": "1.0.15" +//! } +//! }, +//! "dev-dependencies": { +//! "serde": { +//! "version": "1.0.228", +//! "features": ["derive"] +//! } +//! } +//! }); //! -//! The principal macro provided by this crate is `query_value!`. Read [the `query_value` doc] for detailed usage. +//! // Simple query +//! assert_eq!( +//! query_value!(data.package.name -> str).unwrap(), +//! "valq" +//! ); //! -//! Also, there is a `Result`-returning variant of `query_value!`, called [`query_value_result!`]. +//! // Combining dot-notations & bracket-notations +//! assert_eq!( +//! query_value!(data.package.authors[0] -> str).unwrap(), +//! "jiftechnify" +//! ); //! -//! [the `query_value` doc]: crate::query_value -//! [`query_value_result!`]: crate::query_value_result +//! // Deserializing a JSON array into a Vec +//! // Make sure that you put the line: `use serde::Deserialize`! +//! assert_eq!( +//! query_value!(data.package.keywords >> (Vec)).unwrap(), +//! ["macro", "query", "json"], +//! ); +//! +//! // Result-returning variant for useful error +//! let res: valq::Result<&str> = query_value_result!(data.package.readme -> str); +//! if let Err(valq::Error::ValueNotFoundAtPath(path)) = res { +//! assert_eq!(path, ".package.readme"); +//! } else { +//! panic!("should be error"); +//! } +//! +//! // Unwrapping with default value +//! assert_eq!( +//! query_value!(data.package.readme -> str ?? "README.md"), +//! "README.md", +//! ); +//! +//! // "Dynamic" query with bracket-notation +//! let dep_name = "paste"; +//! assert_eq!( +//! query_value!(data.dependencies[dep_name].version -> str).unwrap(), +//! "1.0.15", +//! ); +//! +//! // Put it all together! +//! assert_eq!( +//! query_value!(data["dev-dependencies"].serde.features[0] >> String ?? "none".into()), +//! "derive".to_string(), +//! ); +//! ``` mod error; pub use error::{Error, Result};