#![cfg_attr(not(feature = "std"), no_std)]
#![forbid(unsafe_code)]
#![doc(
html_favicon_url = "https://kura.pro/cmn/images/favicon.ico",
html_logo_url = "https://kura.pro/cmn/images/logos/cmn.svg",
html_root_url = "https://docs.rs/cmn"
)]
#![crate_name = "cmn"]
#![crate_type = "lib"]
#[cfg(feature = "std")]
use serde::{Deserialize, Serialize};
pub mod macros;
pub mod constants;
#[cfg(feature = "std")]
pub use constants::Constants;
#[cfg(feature = "std")]
pub mod words;
#[cfg(feature = "std")]
pub use words::Words;
#[cfg(feature = "std")]
pub mod datetime;
#[cfg(feature = "std")]
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct Common {
#[serde(flatten)]
fields: serde_json::Value,
}
#[cfg(feature = "std")]
impl Common {
pub fn new() -> Self {
Self {
fields: serde_json::Value::Null,
}
}
pub fn constants(&self) -> Constants {
Constants {
..Default::default()
}
}
pub fn words(&self) -> Words {
let words_data = self
.fields
.get("words")
.map(|words_array| {
words_array
.as_array()
.expect("Words data is not an array")
.iter()
.map(|word_value| {
word_value.as_str().unwrap().to_string()
})
.collect::<Vec<String>>()
})
.unwrap_or_default();
Words {
words: words_data.into_iter().collect(),
}
}
pub fn parse(
input: &str,
) -> Result<Self, serde_json::Error> {
match serde_json::from_str::<Common>(input) {
Ok(common) => {
if common.fields.is_null()
|| common.fields.is_object()
&& common
.fields
.as_object()
.unwrap()
.is_empty()
{
Ok(Common::default())
} else {
Ok(common)
}
}
Err(e) => {
eprintln!("JSON parse error: {e}");
Err(e)
}
}
}
}
#[cfg(feature = "std")]
impl Default for Common {
fn default() -> Self {
Self::new()
}
}
#[cfg(feature = "std")]
pub fn run() -> Result<(), Box<dyn std::error::Error>> {
if std::env::var("CMN_TEST_MODE").unwrap_or_default()
== "1"
{
return Err("Simulated error".into());
}
let name = "cmn";
println!("Welcome to `{}` 👋!", { name }.to_uppercase());
println!(
"A Rust library for accessing a collection of \
mathematical and cryptographic constants."
);
Ok(())
}