use crate::interpreter::bytecode::BuiltinId;
#[derive(Clone, Copy)]
pub(crate) enum JsonKind {
Object,
Array,
Str,
Bool,
Int(i128),
Float,
Null,
Other,
}
pub(crate) fn json_type_test(kind: JsonKind, name: BuiltinId) -> Option<bool> {
Some(match name {
BuiltinId::IsObject => matches!(kind, JsonKind::Object),
BuiltinId::IsArray => matches!(kind, JsonKind::Array),
BuiltinId::IsString => matches!(kind, JsonKind::Str),
BuiltinId::IsBoolean => matches!(kind, JsonKind::Bool),
BuiltinId::IsNumber => matches!(kind, JsonKind::Int(_) | JsonKind::Float),
BuiltinId::IsI64 => matches!(kind, JsonKind::Int(v) if i64::try_from(v).is_ok()),
BuiltinId::IsU64 => matches!(kind, JsonKind::Int(v) if u64::try_from(v).is_ok()),
BuiltinId::IsF64 => matches!(kind, JsonKind::Float),
BuiltinId::IsNull => matches!(kind, JsonKind::Null),
_ => return None,
})
}
pub(crate) fn json_accessor(name: BuiltinId) -> bool {
matches!(
name,
BuiltinId::AsStr
| BuiltinId::AsI64
| BuiltinId::AsU64
| BuiltinId::AsF64
| BuiltinId::AsBool
| BuiltinId::AsArray
| BuiltinId::AsArrayMut
| BuiltinId::AsObject
| BuiltinId::AsObjectMut
)
}
pub(crate) fn json_pointer_tokens(pointer: &str) -> Option<Vec<String>> {
if pointer.is_empty() {
return Some(Vec::new());
}
if !pointer.starts_with('/') {
return None;
}
Some(
pointer
.split('/')
.skip(1)
.map(|token| token.replace("~1", "/").replace("~0", "~"))
.collect(),
)
}
pub(crate) fn json_pointer_index(token: &str) -> Option<usize> {
if token.starts_with('+') || (token.starts_with('0') && token.len() != 1) {
return None;
}
token.parse().ok()
}