Write new parser/formatters for Values/IndexableValues
This commit is contained in:
parent
6b93452d3e
commit
d4a941a738
1 changed files with 140 additions and 56 deletions
|
|
@ -179,16 +179,134 @@ 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_)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn indexable_value_to_string(value: IndexableValue) -> String {
|
fn indexable_value_to_string(value: IndexableValue) -> String {
|
||||||
match value {
|
match value {
|
||||||
IndexableValue::String(s) => format!("String({s})"),
|
IndexableValue::String(s) => format!("String({s})"),
|
||||||
IndexableValue::Int(i) => format!("Int({i})"),
|
IndexableValue::Int(i) => format!("Int({i})"),
|
||||||
IndexableValue::Uuid(u) => format!("Uuid({u})"),
|
IndexableValue::Uuid(u) => format!("Uuid({u})"),
|
||||||
IndexableValue::Some(val) => todo!(),
|
IndexableValue::Some(val) => format!("Some({})", indexable_value_to_string(*val)),
|
||||||
IndexableValue::None(type_) => "None()".to_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> {
|
||||||
|
if !str.ends_with(')') {
|
||||||
|
return Err(format!("Invalid IndexableValue: {}", str));
|
||||||
|
}
|
||||||
|
|
||||||
|
if str.starts_with("String(") {
|
||||||
|
let s = str[7..str.len() - 1].to_string();
|
||||||
|
Ok(IndexableValue::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(IndexableValue::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(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)?;
|
||||||
|
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)?;
|
||||||
|
Ok(IndexableValue::None(type_))
|
||||||
|
} else {
|
||||||
|
Err(format!("Invalid IndexableValue: {}", str))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Own string serialization so enums can be used as keys in maps
|
// Own string serialization so enums can be used as keys in maps
|
||||||
impl From<IndexableValue> for String {
|
impl From<IndexableValue> for String {
|
||||||
fn from(value: IndexableValue) -> Self {
|
fn from(value: IndexableValue) -> Self {
|
||||||
|
|
@ -196,71 +314,37 @@ impl From<IndexableValue> for String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<String> for IndexableValue {
|
impl From<DbType> for String {
|
||||||
type Error = String;
|
fn from(type_: DbType) -> Self {
|
||||||
fn try_from(value: String) -> Result<Self, Self::Error> {
|
db_type_to_string(type_)
|
||||||
if !value.ends_with(')') {
|
}
|
||||||
return Err(format!("Invalid IndexableValue: {}", value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if value.starts_with("String(") {
|
impl TryFrom<String> for DbType {
|
||||||
let s = value[7..value.len() - 1].to_string();
|
type Error = String;
|
||||||
Ok(Self::String(s))
|
fn try_from(str: String) -> Result<Self, Self::Error> {
|
||||||
} else if value.starts_with("Int(") {
|
parse_db_type(&str)
|
||||||
let s = value[4..value.len() - 1].to_string();
|
|
||||||
let i = s
|
|
||||||
.parse::<u64>()
|
|
||||||
.map_err(|e| format!("Invalid Int: {}", e))?;
|
|
||||||
Ok(Self::Int(i))
|
|
||||||
} else if value.starts_with("Uuid(") {
|
|
||||||
let s = value[5..value.len() - 1].to_string();
|
|
||||||
let u = s
|
|
||||||
.parse::<u64>()
|
|
||||||
.map_err(|e| format!("Invalid UUID: {}", e))?;
|
|
||||||
Ok(Self::Uuid(u))
|
|
||||||
} else if value.starts_with("Some(") {
|
|
||||||
// TODO: This needs some recursion
|
|
||||||
todo!()
|
|
||||||
} else if value.starts_with("None(") {
|
|
||||||
todo!()
|
|
||||||
} else {
|
|
||||||
Err(format!("Invalid IndexableValue: {}", value))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TryFrom<String> for IndexableValue {
|
||||||
|
type Error = String;
|
||||||
|
fn try_from(str: String) -> Result<Self, Self::Error> {
|
||||||
|
parse_indexable_value(&str)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
impl From<Value> for String {
|
impl From<Value> for String {
|
||||||
fn from(value: Value) -> Self {
|
fn from(value: Value) -> Self {
|
||||||
// match value {
|
value_to_string(value)
|
||||||
// Value::Number(n) => format!("Number({n})"),
|
|
||||||
// Value::Indexable(i) => format!("Indexable({})", String::from(i)),
|
|
||||||
// }
|
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<String> for Value {
|
impl TryFrom<String> for Value {
|
||||||
type Error = String;
|
type Error = String;
|
||||||
fn try_from(value: String) -> Result<Self, Self::Error> {
|
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||||
if !value.ends_with(')') {
|
parse_value(&value)
|
||||||
return Err(format!("Invalid Value: {}", value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// if value.starts_with("Number(") {
|
|
||||||
// let s = value[7..value.len() - 1].to_string();
|
|
||||||
// let n = s
|
|
||||||
// .parse::<f64>()
|
|
||||||
// .map_err(|e| format!("Invalid Number: {}", e))?;
|
|
||||||
// Ok(Self::Number(n))
|
|
||||||
// } else if value.starts_with("Indexable(") {
|
|
||||||
// let s = value[10..value.len() - 1].to_string();
|
|
||||||
// let i = IndexableValue::try_from(s)?;
|
|
||||||
// Ok(Self::Indexable(i))
|
|
||||||
// } else {
|
|
||||||
// Err(format!("Invalid Value: {}", value))
|
|
||||||
// }
|
|
||||||
|
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue