#![no_std]
#![warn(missing_docs)]
extern crate alloc;
use alloc::borrow::Cow;
use alloc::string::ToString;
pub mod binary;
pub mod error;
pub mod text;
pub mod value;
pub use error::{Error, Result};
pub use value::{Obj, Value, Vdf};
pub use text::parse_text;
pub fn parse_binary(input: &[u8]) -> Result<Vdf<'_>> {
binary::parse(input)
}
pub fn parse_shortcuts(input: &[u8]) -> Result<Vdf<'_>> {
binary::parse_shortcuts(input)
}
pub fn parse_appinfo(input: &[u8]) -> Result<Vdf<'_>> {
binary::parse_appinfo(input)
}
pub fn parse_packageinfo(input: &[u8]) -> Result<Vdf<'_>> {
binary::parse_packageinfo(input)
}
impl Vdf<'_> {
pub fn into_owned(self) -> Vdf<'static> {
let (key, value) = self.into_parts();
let owned_key: Cow<'static, str> = match key {
Cow::Borrowed(s) => Cow::Owned(s.to_string()),
Cow::Owned(s) => Cow::Owned(s),
};
Vdf::new(owned_key, value.into_owned())
}
}
impl Value<'_> {
pub fn into_owned(self) -> Value<'static> {
match self {
Value::Str(s) => Value::Str(match s {
Cow::Borrowed(b) => b.to_string().into(),
Cow::Owned(o) => o.into(),
}),
Value::Obj(obj) => Value::Obj(obj.into_owned()),
Value::I32(n) => Value::I32(n),
Value::U64(n) => Value::U64(n),
Value::Float(n) => Value::Float(n),
Value::Pointer(n) => Value::Pointer(n),
Value::Color(c) => Value::Color(c),
}
}
}
impl Obj<'_> {
pub fn into_owned(self) -> Obj<'static> {
let mut new = Obj::new();
for (k, v) in self.iter() {
let owned_key: Cow<'static, str> = match k {
Cow::Borrowed(b) => Cow::Owned(b.to_string()),
Cow::Owned(o) => Cow::Owned(o.clone()),
};
new.insert(owned_key, v.clone().into_owned());
}
new
}
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::vec;
const SHORTCUTS_VDF: &[u8] = &[
0x00, b't', b'e', b's', b't', 0x00, 0x01, b'k', b'e', b'y', 0x00, b'v', b'a', b'l', b'u', b'e', 0x00, 0x08, ];
#[test]
fn test_parse_binary() {
let vdf = parse_binary(SHORTCUTS_VDF).unwrap();
assert!(vdf.as_obj().is_some());
assert_eq!(vdf.key(), "root");
let obj = vdf.as_obj().unwrap();
let test_obj = obj.get("test").and_then(|v| v.as_obj()).unwrap();
assert_eq!(test_obj.get("key").and_then(|v| v.as_str()), Some("value"));
}
#[test]
fn test_parse_shortcuts() {
let vdf = parse_shortcuts(SHORTCUTS_VDF).unwrap();
assert!(vdf.as_obj().is_some());
assert_eq!(vdf.key(), "root");
let obj = vdf.as_obj().unwrap();
let test_obj = obj.get("test").and_then(|v| v.as_obj()).unwrap();
assert_eq!(test_obj.get("key").and_then(|v| v.as_str()), Some("value"));
}
#[test]
fn test_parse_appinfo() {
let mut input = vec![
0x28, 0x44, 0x56, 0x07, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ];
input.resize(76, 0);
let result = parse_appinfo(&input);
if let Err(e) = &result {
panic!("parse_appinfo failed: {:?}", e);
}
assert!(result.is_ok());
let vdf = result.unwrap();
assert!(vdf.key().starts_with("appinfo_universe_"));
}
#[test]
fn test_into_owned_vdf() {
let input = r#""root"
{
"key" "value"
}"#;
let borrowed = parse_text(input).unwrap();
let owned = borrowed.into_owned();
assert_eq!(owned.key(), "root");
}
#[test]
fn test_into_owned_value_str() {
let borrowed = Value::Str("test".into());
let owned = borrowed.into_owned();
assert!(matches!(owned, Value::Str(Cow::Owned(_))));
}
#[test]
fn test_into_owned_value_obj() {
let mut obj = Obj::new();
obj.insert("key", Value::Str("value".into()));
let borrowed = Value::Obj(obj);
let owned = borrowed.into_owned();
assert!(matches!(owned, Value::Obj(_)));
}
#[test]
fn test_into_owned_obj() {
let mut obj = Obj::new();
obj.insert("key", Value::Str("value".into()));
let owned = obj.into_owned();
assert!(owned.get("key").is_some());
}
}