use super::*;
use crate::{Fields, List, Map};
use std::{
borrow::{Borrow, Cow},
error, fmt,
ops::{Deref, DerefMut},
};
#[derive(Eq, PartialOrd, Ord)]
pub enum Value<'a> {
Unit,
Bool(bool),
Num(Number),
Str(Kstr<'a>),
Barr(Barr<'a>),
Tuple(List<'a>),
Cntr(Fields<'a>),
Seq(List<'a>),
Map(Map<'a>),
}
impl<'a> PartialEq for Value<'a> {
fn eq(&self, b: &Self) -> bool {
use Value::*;
match (self, b) {
(Tuple(a), Cntr(b)) if a.is_empty() && b.is_empty() => true,
(Cntr(a), Tuple(b)) if a.is_empty() && b.is_empty() => true,
(Unit, Unit) => true,
(Bool(a), Bool(b)) => a == b,
(Num(a), Num(b)) => a == b,
(Str(a), Str(b)) => a == b,
(Barr(a), Barr(b)) => a == b,
(Tuple(a), Tuple(b)) => a == b,
(Cntr(a), Cntr(b)) => a == b,
(Seq(a), Seq(b)) => a == b,
(Map(a), Map(b)) => a == b,
_ => false,
}
}
}
#[derive(PartialEq, Debug, Eq, Clone)]
pub struct InvalidFieldName(pub Cow<'static, str>);
impl InvalidFieldName {
fn validate(s: &str) -> Result<(), Self> {
let invalid = " /\\\"\t'";
if s.is_empty() {
Err(InvalidFieldName(Cow::Borrowed("name is empty")))
} else if s.chars().next().unwrap().is_ascii_digit() {
Err(InvalidFieldName(Cow::Borrowed(
"name can not begin with digit",
)))
} else {
for c in s.chars() {
if invalid.contains(c) {
return Err(InvalidFieldName(Cow::Owned(format!(
"invalid character '{}' exists in name '{}'",
c, s
))));
}
}
Ok(())
}
}
}
impl error::Error for InvalidFieldName {}
impl fmt::Display for InvalidFieldName {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "invalid field name: {}", self.0)
}
}
impl Value<'static> {
pub fn new_num<T: NumberType>(value: T) -> Self {
Value::Num(value.into())
}
pub const fn new_string(string: String) -> Self {
Value::Str(Kstr::owned(string))
}
pub const fn new_barrv(byte_array: Vec<u8>) -> Self {
Value::Barr(Barr::owned(byte_array))
}
}
impl<'a> Value<'a> {
pub const fn new_str(string: &'a str) -> Self {
Value::Str(Kstr::brwed(string))
}
pub const fn new_barr(byte_array: &'a [u8]) -> Self {
Value::Barr(Barr::brwed(byte_array))
}
pub fn new_cntr<I, S>(iter: I) -> Result<Self, InvalidFieldName>
where
S: Into<Kstr<'a>>,
I: IntoIterator<Item = (S, Kserd<'a>)>,
{
let map: BTreeMap<_, _> = iter.into_iter().map(|(k, v)| (k.into(), v)).collect();
for (k, _) in map.iter() {
InvalidFieldName::validate(k)?;
}
Ok(Value::Cntr(map))
}
pub fn new_map<I>(iter: I) -> Self
where
I: IntoIterator<Item = (Kserd<'a>, Kserd<'a>)>,
{
use std::iter::FromIterator;
let map = BTreeMap::from_iter(iter);
Value::Map(map)
}
}
impl<'a> Value<'a> {
pub fn unit(&self) -> bool {
matches!(&self, Value::Unit)
}
pub fn bool(&self) -> Option<bool> {
match &self {
Value::Bool(val) => Some(*val),
_ => None,
}
}
pub fn bool_mut(&mut self) -> Option<&mut bool> {
match self {
Value::Bool(val) => Some(val),
_ => None,
}
}
pub fn ch(&self) -> Option<char> {
match &self {
Value::Str(val) if val.chars().count() == 1 => val.chars().next(),
_ => None,
}
}
pub fn uint(&self) -> Option<u128> {
match &self {
Value::Num(val) => val.as_u128().ok(),
_ => None,
}
}
pub fn int(&self) -> Option<i128> {
match &self {
Value::Num(val) => val.as_i128().ok(),
_ => None,
}
}
pub fn float(&self) -> Option<f64> {
match &self {
Value::Num(val) => Some(val.as_f64()),
_ => None,
}
}
pub fn num_mut(&mut self) -> Option<&mut Number> {
match self {
Value::Num(val) => Some(val),
_ => None,
}
}
pub fn str(&self) -> Option<&str> {
match &self {
Value::Str(val) => Some(val.as_str()),
_ => None,
}
}
pub fn str_mut(&mut self) -> Option<&mut String> {
match self {
Value::Str(val) => Some(val.to_mut()),
_ => None,
}
}
pub fn barr(&self) -> Option<&[u8]> {
match &self {
Value::Barr(barr) => Some(barr.as_bytes()),
_ => None,
}
}
pub fn barr_mut(&mut self) -> Option<&mut Vec<u8>> {
match self {
Value::Barr(val) => Some(val.to_mut()),
_ => None,
}
}
pub fn tuple(&self) -> Option<&List<'a>> {
match self {
Value::Tuple(val) => Some(val),
_ => None,
}
}
pub fn tuple_mut(&mut self) -> Option<&mut List<'a>> {
match self {
Value::Tuple(val) => Some(val),
_ => None,
}
}
pub fn cntr(&self) -> Option<Accessor<&Fields<'a>>> {
match self {
Value::Cntr(fields) => Some(Accessor(fields)),
_ => None,
}
}
pub fn cntr_mut(&mut self) -> Option<Accessor<&mut Fields<'a>>> {
match self {
Value::Cntr(fields) => Some(Accessor(fields)),
_ => None,
}
}
pub fn seq(&self) -> Option<&List<'a>> {
match self {
Value::Seq(val) => Some(val),
_ => None,
}
}
pub fn seq_mut(&mut self) -> Option<&mut List<'a>> {
match self {
Value::Seq(val) => Some(val),
_ => None,
}
}
pub fn tuple_or_seq(&self) -> Option<&List<'a>> {
match self {
Value::Tuple(x) | Value::Seq(x) => Some(x),
_ => None,
}
}
pub fn tuple_or_seq_mut(&mut self) -> Option<&mut List<'a>> {
match self {
Value::Tuple(x) | Value::Seq(x) => Some(x),
_ => None,
}
}
pub fn map(&self) -> Option<&Map<'a>> {
match self {
Value::Map(val) => Some(val),
_ => None,
}
}
pub fn map_mut(&mut self) -> Option<&mut Map<'a>> {
match self {
Value::Map(val) => Some(val),
_ => None,
}
}
}
impl<'a> Value<'a> {
pub fn into_owned(self) -> Value<'static> {
match self {
Value::Unit => Value::Unit,
Value::Bool(v) => Value::Bool(v),
Value::Num(v) => Value::Num(v),
Value::Str(s) => Value::Str(s.into_owned()),
Value::Barr(b) => Value::Barr(b.into_owned()),
Value::Tuple(seq) => Value::Tuple({
let mut v = Vec::with_capacity(seq.len());
for i in seq {
v.push(i.into_owned())
}
v
}),
Value::Cntr(map) => Value::Cntr({
let mut m = BTreeMap::new();
for (k, v) in map {
m.insert(k.into_owned(), v.into_owned());
}
m
}),
Value::Seq(seq) => Value::Seq({
let mut v = Vec::with_capacity(seq.len());
for i in seq {
v.push(i.into_owned())
}
v
}),
Value::Map(map) => Value::Map({
let mut m = BTreeMap::new();
for (k, v) in map {
m.insert(k.into_owned(), v.into_owned());
}
m
}),
}
}
pub fn mk_brw(&self) -> Value {
match &self {
Value::Unit => Value::Unit,
Value::Bool(v) => Value::Bool(*v),
Value::Num(v) => Value::Num(*v),
Value::Str(v) => Value::Str(Kstr::brwed(v.as_str())),
Value::Barr(v) => Value::Barr(Barr::brwed(v.as_bytes())),
Value::Tuple(seq) => Value::Tuple({
let mut v = Vec::with_capacity(seq.len());
for i in seq {
v.push(i.mk_brw());
}
v
}),
Value::Cntr(map) => Value::Cntr({
let mut m = BTreeMap::new();
for (k, v) in map {
m.insert(Kstr::brwed(k.as_str()), v.mk_brw());
}
m
}),
Value::Seq(seq) => Value::Seq({
let mut v = Vec::with_capacity(seq.len());
for i in seq {
v.push(i.mk_brw());
}
v
}),
Value::Map(map) => Value::Map({
let mut m = BTreeMap::new();
for (k, v) in map {
m.insert(k.mk_brw(), v.mk_brw());
}
m
}),
}
}
}
impl<'a> Clone for Value<'a> {
fn clone(&self) -> Self {
match &self {
Value::Unit => Value::Unit,
Value::Bool(v) => Value::Bool(*v),
Value::Num(v) => Value::Num(*v),
Value::Str(s) => Value::Str(s.clone()),
Value::Barr(b) => Value::Barr(b.clone()),
Value::Tuple(seq) => Value::Tuple(seq.clone()),
Value::Cntr(map) => Value::Cntr(map.clone()),
Value::Seq(seq) => Value::Seq(seq.clone()),
Value::Map(map) => Value::Map(map.clone()),
}
}
}
impl<'a> fmt::Debug for Value<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Value::Unit => write!(f, "Unit"),
Value::Bool(v) => write!(f, "Bool({})", v),
Value::Num(v) => write!(f, "Num({:?})", v),
Value::Str(v) => write!(f, "Str({:?})", v),
Value::Barr(v) => write!(f, "Barr({:?})", v),
Value::Tuple(v) => {
let mut d = f.debug_tuple("Tuple");
for i in v {
d.field(i);
}
d.finish()
}
Value::Cntr(v) => {
let mut d = f.debug_struct("Cntr");
for (k, v) in v {
d.field(k.as_str(), v);
}
d.finish()
}
Value::Seq(v) => f.debug_list().entries(v.iter()).finish(),
Value::Map(v) => f.debug_map().entries(v.iter()).finish(),
}
}
}
#[derive(Debug, PartialEq)]
pub struct Accessor<T>(T);
impl<T> Deref for Accessor<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}
impl<T> DerefMut for Accessor<T> {
fn deref_mut(&mut self) -> &mut T {
&mut self.0
}
}
impl<'a, T> Accessor<T>
where
T: Deref<Target = Fields<'a>>,
{
pub fn get_unit<K>(&self, name: &K) -> Option<()>
where
K: Ord + ?Sized,
Kstr<'a>: Borrow<K>,
{
self.get(name)
.and_then(|v| if v.unit() { Some(()) } else { None })
}
pub fn get_bool<K>(&self, name: &K) -> Option<bool>
where
K: Ord + ?Sized,
Kstr<'a>: Borrow<K>,
{
self.get(name).and_then(|v| v.bool())
}
pub fn get_num<K>(&self, name: &K) -> Option<Number>
where
K: Ord + ?Sized,
Kstr<'a>: Borrow<K>,
{
self.get(name).and_then(|k| match &k.val {
Value::Num(n) => Some(*n),
_ => None,
})
}
pub fn get_str<'b, K>(&'b self, name: &K) -> Option<&'b str>
where
'a: 'b,
K: Ord + ?Sized,
Kstr<'a>: Borrow<K>,
{
self.get(name).and_then(|k| k.str())
}
pub fn get_barr<'b, K>(&'b self, name: &K) -> Option<&'b [u8]>
where
'a: 'b,
K: Ord + ?Sized,
Kstr<'a>: Borrow<K>,
{
self.get(name).and_then(|k| k.barr())
}
pub fn get_tuple<K>(&self, name: &K) -> Option<&List<'a>>
where
K: Ord + ?Sized,
Kstr<'a>: Borrow<K>,
{
self.get(name).and_then(|k| k.tuple())
}
pub fn get_seq<K>(&self, name: &K) -> Option<&List<'a>>
where
K: Ord + ?Sized,
Kstr<'a>: Borrow<K>,
{
self.get(name).and_then(|k| k.seq())
}
pub fn get_tuple_or_seq<K>(&self, name: &K) -> Option<&List<'a>>
where
K: Ord + ?Sized,
Kstr<'a>: Borrow<K>,
{
self.get(name).and_then(|k| k.tuple_or_seq())
}
pub fn get_cntr<K>(&self, name: &K) -> Option<Accessor<&Fields<'a>>>
where
K: Ord + ?Sized,
Kstr<'a>: Borrow<K>,
{
self.get(name).and_then(|k| k.cntr())
}
pub fn get_map<K>(&self, name: &K) -> Option<&Map<'a>>
where
K: Ord + ?Sized,
Kstr<'a>: Borrow<K>,
{
self.get(name).and_then(|k| k.map())
}
}
impl<'a, T> Accessor<T>
where
T: DerefMut<Target = Fields<'a>>,
{
pub fn get_bool_mut<'b, K>(&'b mut self, name: &K) -> Option<&'b mut bool>
where
'a: 'b,
K: Ord + ?Sized,
Kstr<'a>: Borrow<K>,
{
self.get_mut(name).and_then(|v| v.bool_mut())
}
pub fn get_num_mut<'b, K>(&'b mut self, name: &K) -> Option<&'b mut Number>
where
'a: 'b,
K: Ord + ?Sized,
Kstr<'a>: Borrow<K>,
{
self.get_mut(name).and_then(|k| k.num_mut())
}
pub fn get_str_mut<'b, K>(&'b mut self, name: &K) -> Option<&'b mut String>
where
'a: 'b,
K: Ord + ?Sized,
Kstr<'a>: Borrow<K>,
{
self.get_mut(name).and_then(|k| k.str_mut())
}
pub fn get_barr_mut<'b, K>(&'b mut self, name: &K) -> Option<&'b mut Vec<u8>>
where
'a: 'b,
K: Ord + ?Sized,
Kstr<'a>: Borrow<K>,
{
self.get_mut(name).and_then(|k| k.barr_mut())
}
pub fn get_tuple_mut<K>(&mut self, name: &K) -> Option<&mut List<'a>>
where
K: Ord + ?Sized,
Kstr<'a>: Borrow<K>,
{
self.get_mut(name).and_then(|k| k.tuple_mut())
}
pub fn get_seq_mut<K>(&mut self, name: &K) -> Option<&mut List<'a>>
where
K: Ord + ?Sized,
Kstr<'a>: Borrow<K>,
{
self.get_mut(name).and_then(|k| k.seq_mut())
}
pub fn get_tuple_or_seq_mut<K>(&mut self, name: &K) -> Option<&mut List<'a>>
where
K: Ord + ?Sized,
Kstr<'a>: Borrow<K>,
{
self.get_mut(name).and_then(|k| k.tuple_or_seq_mut())
}
pub fn get_cntr_mut<K>(&mut self, name: &K) -> Option<Accessor<&mut Fields<'a>>>
where
K: Ord + ?Sized,
Kstr<'a>: Borrow<K>,
{
self.get_mut(name).and_then(|k| k.cntr_mut())
}
pub fn get_map_mut<K>(&mut self, name: &K) -> Option<&mut Map<'a>>
where
K: Ord + ?Sized,
Kstr<'a>: Borrow<K>,
{
self.get_mut(name).and_then(|k| k.map_mut())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ToKserd;
fn k<'a, T: ToKserd<'a>>(t: T) -> Kserd<'a> {
t.into_kserd().unwrap()
}
#[test]
fn debug_fmt() {
let x = Value::new_barr(&[1, 2, 3]);
assert_eq!(&format!("{:?}", x), "Barr([1, 2, 3])");
let x = Value::Seq(vec![k(101)]);
assert_eq!(
&format!("{:?}", x),
r#"[Kserd { id: Some("i32"), val: Num(Int(101)) }]"#
);
let x = Value::new_map(vec![(k(1), k(2))]);
assert_eq!(
&format!("{:?}", x),
r#"{Kserd { id: Some("i32"), val: Num(Int(1)) }: Kserd { id: Some("i32"), val: Num(Int(2)) }}"#
);
}
#[test]
fn invalid_field_test() {
fn f(s: &str) -> String {
InvalidFieldName::validate(s).unwrap_err().to_string()
};
assert_eq!(&f(""), "invalid field name: name is empty");
assert_eq!(
&f("9name"),
"invalid field name: name can not begin with digit"
);
assert_eq!(
&f("na\tme"),
"invalid field name: invalid character '\t' exists in name 'na\tme'"
);
}
#[test]
fn mutable_testing() {
let mut x = Value::Bool(true);
x.bool_mut().map(|x| *x = false);
assert_eq!(x.bool(), Some(false));
assert_eq!(x.num_mut(), None);
let mut x = Value::new_num(123);
x.num_mut().map(|x| *x = 3.14.into());
assert_eq!(x.float(), Some(3.14));
assert_eq!(x.bool_mut(), None);
assert_eq!(x.str_mut(), None);
assert_eq!(x.barr_mut(), None);
let mut x = Value::new_str("Hello");
x.str_mut().map(|x| x.push_str(", world!"));
assert_eq!(x.str(), Some("Hello, world!"));
let mut x = Value::new_barr([0, 1, 2].as_ref());
x.barr_mut().map(|x| x.push(3));
assert_eq!(x.barr(), Some([0, 1, 2, 3].as_ref()));
assert_eq!(x.tuple_or_seq(), None);
assert_eq!(x.tuple_or_seq_mut(), None);
let mut x = Value::Tuple(vec![k("a"), k("b")]);
x.tuple_mut().map(|x| x.push(k("c")));
assert_eq!(x.tuple(), Some(&vec![k("a"), k("b"), k("c")]));
assert_eq!(x.seq(), None);
assert_eq!(x.seq_mut(), None);
assert_eq!(x.tuple_or_seq(), Some(&vec![k("a"), k("b"), k("c")]));
let mut x = Value::Seq(vec![k("a"), k("b")]);
x.seq_mut().map(|x| x.push(k("c")));
assert_eq!(x.seq(), Some(&vec![k("a"), k("b"), k("c")]));
assert_eq!(x.tuple(), None);
assert_eq!(x.tuple_mut(), None);
assert_eq!(x.tuple_or_seq(), Some(&vec![k("a"), k("b"), k("c")]));
assert_eq!(x.map(), None);
assert_eq!(x.map_mut(), None);
}
#[test]
fn conversion_testing() {
let unit = Value::Unit.to_owned();
assert_eq!(unit, Value::Unit);
let b = Value::Bool(true).to_owned();
assert_eq!(b, Value::Bool(true));
let n = Value::new_num(3.14).to_owned();
assert_eq!(n, Value::new_num(3.14));
let s = Value::new_str("What!?").to_owned();
assert_eq!(s, Value::new_str("What!?"));
let barr = Value::new_barr([0, 1].as_ref()).to_owned();
assert_eq!(barr, Value::new_barr([0, 1].as_ref()));
let b = Value::Bool(true);
assert_eq!(b, b.clone());
let barr = Value::new_barr([0, 1].as_ref()).to_owned();
assert_eq!(barr, barr.clone());
fn test(v: Kserd) {
let vclone = v.clone();
assert_eq!(v.to_owned(), vclone);
};
test(Kserd::new(Value::Tuple(vec![
Kserd::new_str("Hello"),
Kserd::new_num(3.14),
])));
test(Kserd::new_cntr(vec![("a", Kserd::new_unit())]).unwrap());
test(Kserd::new(Value::Seq(vec![
Kserd::new_str("Hello"),
Kserd::new_num(3.14),
])));
test(Kserd::new_map(vec![(Kserd::new_unit(), Kserd::new_num(0))]));
let unit = Value::Unit;
assert_eq!(unit, unit.mk_brw());
let b = Value::Bool(true);
assert_eq!(b, b.mk_brw());
let n = Value::new_num(3.14);
assert_eq!(n, n.mk_brw());
let s = Value::new_str("What!?");
assert_eq!(s, s.mk_brw());
let barr = Value::new_barr([0, 1].as_ref());
assert_eq!(barr, barr.mk_brw());
fn test2(v: Kserd) {
assert_eq!(v.mk_brw(), v);
};
test2(Kserd::new(Value::Tuple(vec![
Kserd::new_str("Hello"),
Kserd::new_num(3.14),
])));
test2(Kserd::new_cntr(vec![("a", Kserd::new_unit())]).unwrap());
test2(Kserd::new(Value::Seq(vec![
Kserd::new_str("Hello"),
Kserd::new_num(3.14),
])));
test2(Kserd::new_map(vec![(Kserd::new_unit(), Kserd::new_num(0))]));
}
#[test]
fn into_owned_test() {
use crate::to_kserd::ToKserd;
let prims = Kserd::new_cntr(vec![
("unit", Kserd::new_unit()),
("bool", Kserd::new_bool(true)),
("num", Kserd::new_num(1.01234)),
("str", Kserd::new_str("Hello, world!")),
("barr", Kserd::new_barr([0, 1, 2, 4, 8].as_ref())),
])
.unwrap();
let nested = Kserd::new_cntr(vec![
("prims", prims.clone()),
(
"tuple",
Kserd::new(Value::Tuple(vec![prims.clone(), prims.clone()])),
),
(
"seq",
Kserd::new(Value::Seq(vec![
prims.clone(),
prims.clone(),
prims.clone(),
prims.clone(),
])),
),
(
"map",
Kserd::new_map(vec![
("first".into_kserd().unwrap(), prims.clone()),
("second".into_kserd().unwrap(), prims.clone()),
]),
),
])
.unwrap();
let nested_owned = nested.clone().into_owned();
assert_eq!(nested, nested_owned);
}
#[test]
fn cntr_accessor() {
let mut x = Value::new_num(101);
assert_eq!(x.cntr(), None);
assert_eq!(x.cntr_mut(), None);
let cntr = Value::new_cntr(vec![
("a", Kserd::new_unit()),
("b", Kserd::new_bool(false)),
("c", Kserd::new_num(101)),
("d", Kserd::new_str("hello")),
("e", Kserd::new_barr(&[0])),
("f", Kserd::new(Value::Tuple(vec![k(1)]))),
("g", Kserd::new(Value::Seq(vec![k(2)]))),
("h", Kserd::new_cntr(vec![("a", k(()))]).unwrap()),
("i", Kserd::new_map(vec![(k(()), k(2))])),
])
.unwrap();
let x = cntr.cntr().unwrap();
assert_eq!(x.get_unit("a"), Some(()));
assert_eq!(x.get_num("a"), None);
assert_eq!(x.get_bool("b"), Some(false));
assert_eq!(x.get_num("c"), Some(101.into()));
assert_eq!(x.get_str("d"), Some("hello"));
assert_eq!(x.get_barr("e"), Some(&[0u8] as &[u8]));
assert_eq!(x.get_tuple("f"), Some(&vec![k(1)]));
assert_eq!(x.get_seq("g"), Some(&vec![k(2)]));
assert_eq!(x.get_tuple_or_seq("f"), Some(&vec![k(1)]));
assert_eq!(x.get_tuple_or_seq("g"), Some(&vec![k(2)]));
assert_eq!(x.get_cntr("h").is_some(), true);
assert_eq!(x.get_map("i").is_some(), true);
}
#[test]
fn cntr_mut_accessor() {
let mut x = Value::new_num(101);
assert_eq!(x.cntr(), None);
assert_eq!(x.cntr_mut(), None);
let mut cntr = Value::new_cntr(vec![
("a", Kserd::new_unit()),
("b", Kserd::new_bool(false)),
("c", Kserd::new_num(101)),
("d", Kserd::new_str("hello")),
("e", Kserd::new_barr(&[0])),
("f", Kserd::new(Value::Tuple(vec![k(1)]))),
("g", Kserd::new(Value::Seq(vec![k(2)]))),
("h", Kserd::new_cntr(vec![("a", k(()))]).unwrap()),
("i", Kserd::new_map(vec![(k(()), k(2))])),
])
.unwrap();
let mut x = cntr.cntr_mut().unwrap();
assert_eq!(x.get_num_mut("a"), None);
assert_eq!(x.get_bool_mut("b"), Some(&mut false));
assert_eq!(x.get_num_mut("c"), Some(&mut 101.into()));
assert_eq!(x.get_str_mut("d"), Some(&mut String::from("hello")));
assert_eq!(x.get_barr_mut("e"), Some(&mut vec![0u8]));
assert_eq!(x.get_tuple_mut("f"), Some(&mut vec![k(1)]));
assert_eq!(x.get_seq_mut("g"), Some(&mut vec![k(2)]));
assert_eq!(x.get_tuple_or_seq_mut("f"), Some(&mut vec![k(1)]));
assert_eq!(x.get_tuple_or_seq_mut("g"), Some(&mut vec![k(2)]));
assert_eq!(x.get_cntr_mut("h").is_some(), true);
assert_eq!(x.get_map_mut("i").is_some(), true);
}
#[test]
fn accessor_both() {
let mut x = Value::new_cntr(vec![("a", Kserd::new_str("Hello"))]).unwrap();
let mut accessor = x.cntr_mut().unwrap();
assert_eq!(accessor.get_str("a"), Some("Hello"));
accessor.get_str_mut("a").map(|s| s.push_str(", world!"));
assert_eq!(accessor.get_str("a"), Some("Hello, world!"));
}
}