use std::borrow::Cow;
use std::str::{self, FromStr};
use crate::{
AccessionIntCode, CURIE, ControlledVocabulary, Param, ParamLike, ParamValue, ParamValueParseError, Unit, Value, ValueRef
};
#[derive(Debug, Clone, Default, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct ParamCow<'a> {
pub name: Cow<'a, str>,
pub value: ValueRef<'a>,
pub accession: Option<AccessionIntCode>,
pub controlled_vocabulary: Option<ControlledVocabulary>,
pub unit: Unit,
}
impl<'a> ParamValue for ParamCow<'a> {
fn is_empty(&self) -> bool {
<ValueRef<'a> as ParamValue>::is_empty(&self.value)
}
fn is_i64(&self) -> bool {
<ValueRef<'a> as ParamValue>::is_i64(&self.value)
}
fn is_f64(&self) -> bool {
<ValueRef<'a> as ParamValue>::is_f64(&self.value)
}
fn is_buffer(&self) -> bool {
<ValueRef<'a> as ParamValue>::is_buffer(&self.value)
}
fn is_str(&self) -> bool {
<ValueRef<'a> as ParamValue>::is_str(&self.value)
}
fn to_f64(&self) -> Result<f64, ParamValueParseError> {
<ValueRef<'a> as ParamValue>::to_f64(&self.value)
}
fn to_i64(&self) -> Result<i64, ParamValueParseError> {
<ValueRef<'a> as ParamValue>::to_i64(&self.value)
}
fn to_str(&self) -> Cow<'_, str> {
<ValueRef<'a> as ParamValue>::to_str(&self.value)
}
fn to_buffer(&self) -> Result<Cow<'_, [u8]>, ParamValueParseError> {
<ValueRef<'a> as ParamValue>::to_buffer(&self.value)
}
fn parse<T: FromStr>(&self) -> Result<T, T::Err> {
<ValueRef<'a> as ParamValue>::parse(&self.value)
}
fn as_bytes(&self) -> Cow<'_, [u8]> {
<ValueRef<'a> as ParamValue>::as_bytes(&self.value)
}
fn as_ref(&self) -> ValueRef<'_> {
<ValueRef<'a> as ParamValue>::as_ref(&self.value)
}
fn data_len(&self) -> usize {
<ValueRef<'a> as ParamValue>::data_len(&self.value)
}
fn is_boolean(&self) -> bool {
<ValueRef<'a> as ParamValue>::is_boolean(&self.value)
}
fn to_bool(&self) -> Result<bool, ParamValueParseError> {
<ValueRef<'a> as ParamValue>::to_bool(&self.value)
}
fn is_list(&self) -> bool {
<ValueRef<'a> as ParamValue>::is_list(&self.value)
}
fn as_slice(&self) -> Cow<'_, [Value]> {
<ValueRef<'a> as ParamValue>::as_slice(&self.value)
}
}
impl ParamCow<'static> {
pub const fn const_new(
name: &'static str,
value: ValueRef<'static>,
accession: Option<AccessionIntCode>,
controlled_vocabulary: Option<ControlledVocabulary>,
unit: Unit,
) -> Self {
Self {
name: Cow::Borrowed(name),
value,
accession,
controlled_vocabulary,
unit,
}
}
}
impl<'a> ParamCow<'a> {
pub fn new(
name: Cow<'a, str>,
value: ValueRef<'a>,
accession: Option<AccessionIntCode>,
controlled_vocabulary: Option<ControlledVocabulary>,
unit: Unit,
) -> Self {
Self {
name,
value,
accession,
controlled_vocabulary,
unit,
}
}
pub fn parse<T: str::FromStr>(&self) -> Result<T, T::Err> {
self.value.parse::<T>()
}
pub const fn is_controlled(&self) -> bool {
self.accession.is_some()
}
pub const fn curie(&self) -> Option<CURIE> {
match (self.controlled_vocabulary, self.accession) {
(Some(cv), Some(acc)) => Some(CURIE::new(cv, acc)),
_ => None,
}
}
}
impl<'a> ParamLike for ParamCow<'a> {
fn name(&self) -> &str {
&self.name
}
fn value(&self) -> ValueRef<'a> {
self.value.clone()
}
fn accession(&self) -> Option<AccessionIntCode> {
self.accession
}
fn controlled_vocabulary(&self) -> Option<ControlledVocabulary> {
self.controlled_vocabulary
}
fn unit(&self) -> Unit {
self.unit
}
}
impl<'a> From<ParamCow<'a>> for Param {
fn from(value: ParamCow<'a>) -> Self {
Param {
name: value.name.into_owned(),
value: value.value.into(),
accession: value.accession,
controlled_vocabulary: value.controlled_vocabulary,
unit: value.unit,
}
}
}
impl PartialEq<CURIE> for ParamCow<'_> {
fn eq(&self, other: &CURIE) -> bool {
other.eq(self)
}
}
impl<'a> AsRef<ValueRef<'a>> for ParamCow<'a> {
fn as_ref(&self) -> &ValueRef<'a> {
&self.value
}
}