Cleanup
This commit is contained in:
parent
ae4061980e
commit
af5490e2dc
1 changed files with 144 additions and 128 deletions
|
|
@ -28,7 +28,6 @@ pub enum Value {
|
|||
None(DbType),
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Eq, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(try_from = "String", into = "String")]
|
||||
pub enum IndexableValue {
|
||||
|
|
@ -91,6 +90,37 @@ impl DbType {
|
|||
}
|
||||
}
|
||||
|
||||
fn to_json_key_string(self) -> String {
|
||||
match self {
|
||||
DbType::String => format!("String()"),
|
||||
DbType::Int => format!("Int()"),
|
||||
DbType::Number => format!("Number()"),
|
||||
DbType::Uuid => format!("Uuid()"),
|
||||
DbType::Option(type_) => format!("Option({})", type_.to_json_key_string()),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_json_key_string(str: &str) -> Result<DbType, String> {
|
||||
if !str.ends_with(')') {
|
||||
return Err(format!("Invalid DbType: {}", str));
|
||||
}
|
||||
|
||||
if str.starts_with("String(") {
|
||||
Ok(DbType::String)
|
||||
} else if str.starts_with("Int(") {
|
||||
Ok(DbType::Int)
|
||||
} else if str.starts_with("Number(") {
|
||||
Ok(DbType::Number)
|
||||
} else if str.starts_with("Uuid(") {
|
||||
Ok(DbType::Uuid)
|
||||
} else if str.starts_with("Option(") {
|
||||
let s = &str[7..str.len() - 1];
|
||||
Ok(DbType::Option(Box::new(Self::parse_json_key_string(s)?)))
|
||||
} else {
|
||||
Err(format!("Invalid DbType: {}", str))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_oid(&self) -> i32 {
|
||||
// match self {
|
||||
// Self::String => 25,
|
||||
|
|
@ -135,6 +165,58 @@ impl Value {
|
|||
}
|
||||
}
|
||||
|
||||
fn to_json_key_string(self) -> String {
|
||||
match self {
|
||||
Self::Number(x) => format!("Number({x})"),
|
||||
Self::String(s) => format!("String({s})"),
|
||||
Self::Int(i) => format!("Int({i})"),
|
||||
Self::Uuid(u) => format!("Uuid({u})"),
|
||||
Self::Some(val) => format!("Some({})", val.to_json_key_string()),
|
||||
Self::None(_type_) => "None()".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
// We don't really need this, since only indexable values are keys in maps. It is here for consistency.
|
||||
fn parse_json_key_string(str: &str) -> Result<Self, String> {
|
||||
if !str.ends_with(')') {
|
||||
return Err(format!("Invalid IndexableValue: {}", str));
|
||||
}
|
||||
|
||||
if str.starts_with("Number(") {
|
||||
let s = str[7..str.len() - 1].to_string();
|
||||
let n = s
|
||||
.parse::<f64>()
|
||||
.map_err(|e| format!("Invalid Number: {}", e))?;
|
||||
Ok(Self::Number(n))
|
||||
} else if str.starts_with("String(") {
|
||||
let s = str[7..str.len() - 1].to_string();
|
||||
Ok(Self::String(s))
|
||||
} else if str.starts_with("Int(") {
|
||||
let s = str[4..str.len() - 1].to_string();
|
||||
let i = s
|
||||
.parse::<u64>()
|
||||
.map_err(|e| format!("Invalid Int: {}", e))?;
|
||||
Ok(Self::Int(i))
|
||||
} else if str.starts_with("Uuid(") {
|
||||
let s = str[5..str.len() - 1].to_string();
|
||||
let u = s
|
||||
.parse::<u64>()
|
||||
.map_err(|e| format!("Invalid UUID: {}", e))?;
|
||||
Ok(Self::Uuid(u))
|
||||
} else if str.starts_with("Some(") {
|
||||
let s = str[5..str.len() - 1].to_string();
|
||||
let val: Value = Self::parse_json_key_string(&s)?;
|
||||
Ok(Self::Some(Box::new(val)))
|
||||
} else if str.starts_with("None(") {
|
||||
let s = str[5..str.len() - 1].to_string();
|
||||
let type_: DbType = TryFrom::try_from(s)?;
|
||||
Ok(Value::None(type_))
|
||||
} else {
|
||||
Err(format!("Invalid IndexableValue: {}", str))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn as_text_bytes(&self) -> Vec<u8> {
|
||||
// match self {
|
||||
// Self::Number(n) => format!("{n}").into_bytes(),
|
||||
|
|
@ -179,100 +261,28 @@ impl Value {
|
|||
}
|
||||
}
|
||||
|
||||
// ===formatting===
|
||||
fn db_type_to_string(type_: DbType) -> String {
|
||||
match type_ {
|
||||
DbType::String => format!("String()"),
|
||||
DbType::Int => format!("Int()"),
|
||||
DbType::Number => format!("Number()"),
|
||||
DbType::Uuid => format!("Uuid()"),
|
||||
DbType::Option(type_) => format!("Option({})", db_type_to_string(*type_)),
|
||||
impl IndexableValue {
|
||||
fn to_value(self) -> Value {
|
||||
match self {
|
||||
IndexableValue::String(str) => Value::String(str),
|
||||
IndexableValue::Int(n) => Value::Int(n),
|
||||
IndexableValue::Uuid(id) => Value::Uuid(id),
|
||||
IndexableValue::Some(indexable_value) => Value::Some(Box::new(indexable_value.to_value())),
|
||||
IndexableValue::None(type_) => Value::None(type_),
|
||||
}
|
||||
}
|
||||
|
||||
fn indexable_value_to_string(value: IndexableValue) -> String {
|
||||
match value {
|
||||
fn to_json_key_string(self) -> String {
|
||||
match self {
|
||||
IndexableValue::String(s) => format!("String({s})"),
|
||||
IndexableValue::Int(i) => format!("Int({i})"),
|
||||
IndexableValue::Uuid(u) => format!("Uuid({u})"),
|
||||
IndexableValue::Some(val) => format!("Some({})", indexable_value_to_string(*val)),
|
||||
IndexableValue::Some(val) => format!("Some({})", val.to_json_key_string()),
|
||||
IndexableValue::None(_type_) => "None()".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn value_to_string(value: Value) -> String {
|
||||
match value {
|
||||
Value::Number(x) => format!("Number({x})"),
|
||||
Value::String(s) => format!("String({s})"),
|
||||
Value::Int(i) => format!("Int({i})"),
|
||||
Value::Uuid(u) => format!("Uuid({u})"),
|
||||
Value::Some(val) => format!("Some({})", value_to_string(*val)),
|
||||
Value::None(_type_) => "None()".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
// ===parsing===
|
||||
fn parse_db_type(str: &str) -> Result<DbType, String> {
|
||||
if !str.ends_with(')') {
|
||||
return Err(format!("Invalid DbType: {}", str));
|
||||
}
|
||||
|
||||
if str.starts_with("String(") {
|
||||
Ok(DbType::String)
|
||||
} else if str.starts_with("Int(") {
|
||||
Ok(DbType::Int)
|
||||
} else if str.starts_with("Number(") {
|
||||
Ok(DbType::Number)
|
||||
} else if str.starts_with("Uuid(") {
|
||||
Ok(DbType::Uuid)
|
||||
} else if str.starts_with("Option(") {
|
||||
let s = &str[7..str.len() - 1];
|
||||
Ok(DbType::Option(Box::new(parse_db_type(s)?)))
|
||||
} else {
|
||||
Err(format!("Invalid DbType: {}", str))
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_value(str: &str) -> Result<Value, String> {
|
||||
if !str.ends_with(')') {
|
||||
return Err(format!("Invalid IndexableValue: {}", str));
|
||||
}
|
||||
|
||||
if str.starts_with("Number(") {
|
||||
let s = str[7..str.len() - 1].to_string();
|
||||
let n = s
|
||||
.parse::<f64>()
|
||||
.map_err(|e| format!("Invalid Number: {}", e))?;
|
||||
Ok(Value::Number(n))
|
||||
} else if str.starts_with("String(") {
|
||||
let s = str[7..str.len() - 1].to_string();
|
||||
Ok(Value::String(s))
|
||||
} else if str.starts_with("Int(") {
|
||||
let s = str[4..str.len() - 1].to_string();
|
||||
let i = s
|
||||
.parse::<u64>()
|
||||
.map_err(|e| format!("Invalid Int: {}", e))?;
|
||||
Ok(Value::Int(i))
|
||||
} else if str.starts_with("Uuid(") {
|
||||
let s = str[5..str.len() - 1].to_string();
|
||||
let u = s
|
||||
.parse::<u64>()
|
||||
.map_err(|e| format!("Invalid UUID: {}", e))?;
|
||||
Ok(Value::Uuid(u))
|
||||
} else if str.starts_with("Some(") {
|
||||
let s = str[5..str.len() - 1].to_string();
|
||||
let val: Value = parse_value(&s)?;
|
||||
Ok(Value::Some(Box::new(val)))
|
||||
} else if str.starts_with("None(") {
|
||||
let s = str[5..str.len() - 1].to_string();
|
||||
let type_: DbType = TryFrom::try_from(s)?;
|
||||
Ok(Value::None(type_))
|
||||
} else {
|
||||
Err(format!("Invalid IndexableValue: {}", str))
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_indexable_value(str: &str) -> Result<IndexableValue, String> {
|
||||
fn parse_json_key_string(str: &str) -> Result<Self, String> {
|
||||
if !str.ends_with(')') {
|
||||
return Err(format!("Invalid IndexableValue: {}", str));
|
||||
}
|
||||
|
|
@ -294,56 +304,62 @@ fn parse_indexable_value(str: &str) -> Result<IndexableValue, String> {
|
|||
Ok(IndexableValue::Uuid(u))
|
||||
} else if str.starts_with("Some(") {
|
||||
let s = str[5..str.len() - 1].to_string();
|
||||
let val: IndexableValue = parse_indexable_value(&s)?;
|
||||
let val: IndexableValue = Self::parse_json_key_string(&s)?;
|
||||
Ok(IndexableValue::Some(Box::new(val)))
|
||||
} else if str.starts_with("None(") {
|
||||
let s = str[5..str.len() - 1].to_string();
|
||||
let type_: DbType = parse_db_type(&s)?;
|
||||
let type_: DbType = DbType::parse_json_key_string(&s)?;
|
||||
Ok(IndexableValue::None(type_))
|
||||
} else {
|
||||
Err(format!("Invalid IndexableValue: {}", str))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<IndexableValue> for Value {
|
||||
fn from(indexable_value: IndexableValue) -> Self {
|
||||
indexable_value.to_value()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Own string serialization so enums can be used as keys in maps
|
||||
impl From<IndexableValue> for String {
|
||||
fn from(value: IndexableValue) -> Self {
|
||||
indexable_value_to_string(value)
|
||||
value.to_json_key_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DbType> for String {
|
||||
fn from(type_: DbType) -> Self {
|
||||
db_type_to_string(type_)
|
||||
type_.to_json_key_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<String> for DbType {
|
||||
type Error = String;
|
||||
fn try_from(str: String) -> Result<Self, Self::Error> {
|
||||
parse_db_type(&str)
|
||||
Self::parse_json_key_string(&str)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<String> for IndexableValue {
|
||||
type Error = String;
|
||||
fn try_from(str: String) -> Result<Self, Self::Error> {
|
||||
parse_indexable_value(&str)
|
||||
Self::parse_json_key_string(&str)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Value> for String {
|
||||
fn from(value: Value) -> Self {
|
||||
value_to_string(value)
|
||||
value.to_json_key_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<String> for Value {
|
||||
type Error = String;
|
||||
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||
parse_value(&value)
|
||||
Value::parse_json_key_string(&value)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue