oxide_eval 0.1.2

Oxide Eval is a simple Javascript Evaluator based on oxc.
Documentation
use anyhow::{anyhow, bail, Result};
use semver::Version;
use serde::{Deserialize, Serialize};
use serde_json::Value;

use crate::util::value_to_number;

#[derive(Serialize, Deserialize)]
pub struct SemverWrapper {
    pub version: Version,
}

impl SemverWrapper {
    pub fn new(major: Value, minor: Value, patch: Value) -> Result<Self> {
        let major = value_to_number(major)? as u64;
        let minor = value_to_number(minor)? as u64;
        let patch = value_to_number(patch)? as u64;
        Ok(SemverWrapper {
            version: Version::new(major, minor, patch),
        })
    }
    pub fn from_value(value: Value) -> Result<Self> {
        match value {
            Value::String(value) => Ok(SemverWrapper {
                version: Version::parse(&value)?,
            }),
            Value::Array(value) => {
                if let (Some(major), Some(minor), Some(patch)) =
                    (value.get(0), value.get(1), value.get(2))
                {
                    Self::new(major.to_owned(), minor.to_owned(), patch.to_owned())
                } else {
                    bail!("array requires size of 3")
                }
            }
            Value::Object(mut value) => {
                let major = value
                    .remove("major")
                    .ok_or_else(|| anyhow!("Missing 'major' field"))?;
                let minor = value
                    .remove("minor")
                    .ok_or_else(|| anyhow!("Missing 'minor' field"))?;
                let patch = value
                    .remove("patch")
                    .ok_or_else(|| anyhow!("Missing 'patch' field"))?;
                Self::new(major, minor, patch)
            }
            _ => bail!("unsupported value type for semver parser: {:?}", value),
        }
    }
    pub fn from_values(mut args: Vec<Value>) -> Result<Self> {
        match args.len() {
            1 => Self::from_value(args.remove(0)),
            3 => {
                let patch = args.pop().unwrap();
                let minor = args.pop().unwrap();
                let major = args.pop().unwrap();
                Self::new(major, minor, patch)
            }
            _ => bail!("semver requires either 1 or 3 args"),
        }
    }
}