use std::borrow::Cow;
use cityjson::prelude::{BorrowedStringStorage, OwnedStringStorage};
use cityjson::resources::storage::StringStorage;
use cityjson::v2_0::{CityModel, OwnedCityModel};
use crate::de::build::build_model;
use crate::de::root::parse_root;
use crate::errors::{Error, Result};
pub trait ParseStringStorage<'de>: StringStorage {
fn store(value: &'de str) -> Self::String;
fn store_cow(value: Cow<'de, str>) -> Result<Self::String>;
}
impl<'de> ParseStringStorage<'de> for OwnedStringStorage {
fn store(value: &'de str) -> String {
value.to_owned()
}
fn store_cow(value: Cow<'de, str>) -> Result<String> {
Ok(value.into_owned())
}
}
impl<'de> ParseStringStorage<'de> for BorrowedStringStorage<'de> {
fn store(value: &'de str) -> &'de str {
value
}
fn store_cow(value: Cow<'de, str>) -> Result<&'de str> {
match value {
Cow::Borrowed(s) => Ok(s),
Cow::Owned(_) => Err(Error::InvalidValue(
"attribute string contains JSON escape sequences; not supported in borrowed mode"
.to_owned(),
)),
}
}
}
pub fn from_str<'de, SS>(input: &'de str) -> Result<CityModel<u32, SS>>
where
SS: ParseStringStorage<'de>,
SS::String: From<&'de str>,
{
let raw = parse_root(input)?;
build_model::<SS>(raw)
}
pub(crate) fn from_str_owned(input: &str) -> Result<OwnedCityModel> {
from_str::<OwnedStringStorage>(input)
}