use std::fmt::{Display, Formatter};
use crate::app_system_error;
use crate::tina::data::AppResult;
use serde_json::Value;
use super::app_error::AppError;
#[derive(Debug, Clone, PartialOrd, PartialEq, Eq, Ord, Hash)]
pub enum Id {
String(String),
Number(i64),
}
impl Id {
pub fn from_json_value(value: serde_json::Value) -> AppResult<Self> {
match value {
Value::Number(v) => match v.as_i64() {
None => match v.as_u64() {
None => Err(crate::app_system_error!("can not parse {} to Id.", v)),
Some(v) => Ok(Id::Number(v as i64)),
},
Some(v) => Ok(Id::Number(v)),
},
Value::String(v) => Ok(Id::String(v)),
_ => Err(crate::app_system_error!("can not parse {} to Id.", value)),
}
}
#[cfg(feature = "rbs")]
pub fn from_rbatis_value(value: rbs::Value) -> AppResult<Self> {
match value {
rbs::Value::F32(v) => Ok(Id::from_i64(v as i64)),
rbs::Value::F64(v) => Ok(Id::from_i64(v as i64)),
rbs::Value::I32(v) => Ok(Id::from_i64(v as i64)),
rbs::Value::I64(v) => Ok(Id::from_i64(v)),
rbs::Value::U32(v) => Ok(Id::from_i64(v as i64)),
rbs::Value::U64(v) => Ok(Id::from_i64(v as i64)),
rbs::Value::String(v) => Ok(Id::from_string(v)),
_ => Err(crate::app_system_error!("can not parse {} to Id.", value)),
}
}
pub fn from_i64(value: i64) -> Self {
Id::Number(value)
}
pub fn from_u64(value: u64) -> Self {
Id::Number(value as i64)
}
pub fn from_string(value: String) -> Self {
Id::String(value)
}
}
impl TryInto<i64> for Id {
type Error = AppError;
fn try_into(self) -> Result<i64, Self::Error> {
match self {
Id::String(v) => v.parse().map_err(|_| app_system_error!("can not parse Id to i64 with value {}", v)),
Id::Number(v) => Ok(v),
}
}
}
impl TryInto<String> for Id {
type Error = AppError;
fn try_into(self) -> Result<String, Self::Error> {
match self {
Id::String(v) => Ok(v),
Id::Number(v) => Ok(v.to_string()),
}
}
}
impl Default for Id {
fn default() -> Self {
Id::from_i64(0i64)
}
}
impl Display for Id {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
match &self {
Id::String(v) => v.fmt(f),
Id::Number(v) => v.fmt(f),
}
}
}
impl AsRef<Id> for Id {
fn as_ref(&self) -> &Id {
self
}
}
pub trait ToId {
fn to_ids(&self) -> AppResult<Vec<Id>>;
fn to_id(&self) -> AppResult<Id>;
}
impl<T> ToId for T
where
T: AsRef<str>,
{
fn to_ids(&self) -> AppResult<Vec<Id>> {
let s = self.as_ref();
let mut ids = Vec::new();
for c in s.split(',') {
let id = Id::from_i64(c.trim().parse().map_err(|err| app_system_error!("转换i64失败: {}, reason: {:?}", c, err))?);
ids.push(id);
}
Ok(ids)
}
fn to_id(&self) -> AppResult<Id> {
let s = self.as_ref();
let id = Id::from_i64(s.trim().parse().map_err(|err| app_system_error!("转换i64失败: {}, reason: {:?}", s, err))?);
Ok(id)
}
}
mod ser {
use crate::tina::data::id::Id;
use serde::{Serialize, Serializer};
impl Serialize for Id {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
#[cfg(feature = "bson")]
{
if std::any::type_name::<S>() == std::any::type_name::<bson::de::Deserializer>() {
return match &self {
Id::String(v) => {
let object_id = bson::oid::ObjectId::parse_str(v.as_str()).map_err(serde::ser::Error::custom)?;
object_id.serialize(serializer)
}
Id::Number(v) => v.serialize(serializer),
};
}
}
match &self {
Id::String(v) => serializer.serialize_str(v.as_str()),
Id::Number(v) => serializer.serialize_i64(*v),
}
}
}
}
mod de {
use crate::tina::data::id::Id;
use serde::de::{Error, Visitor};
use serde::{Deserialize, Deserializer};
use std::fmt::Formatter;
struct IdVisitor;
impl<'de> Visitor<'de> for IdVisitor {
type Value = Id;
fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
formatter.write_str("Id must be integer value")
}
fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Id::from_i64(v as i64))
}
fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Id::from_i64(v as i64))
}
fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Id::from_i64(v as i64))
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Id::from_i64(v))
}
fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Id::from_u64(v as u64))
}
fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Id::from_u64(v as u64))
}
fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Id::from_u64(v as u64))
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Id::from_u64(v))
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: Error,
{
let v = v.parse::<u64>().map_err(E::custom)?;
Ok(Id::from_u64(v))
}
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
where
E: Error,
{
let v = v.parse::<u64>().map_err(E::custom)?;
Ok(Id::from_u64(v))
}
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: Error,
{
let v = v.parse::<u64>().map_err(E::custom)?;
Ok(Id::from_u64(v))
}
}
impl<'de> Deserialize<'de> for Id {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(IdVisitor)
}
}
}