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),
|
None(DbType),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Eq, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Eq, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
#[serde(try_from = "String", into = "String")]
|
#[serde(try_from = "String", into = "String")]
|
||||||
pub enum IndexableValue {
|
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 {
|
pub fn type_oid(&self) -> i32 {
|
||||||
// match self {
|
// match self {
|
||||||
// Self::String => 25,
|
// 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> {
|
pub fn as_text_bytes(&self) -> Vec<u8> {
|
||||||
// match self {
|
// match self {
|
||||||
// Self::Number(n) => format!("{n}").into_bytes(),
|
// Self::Number(n) => format!("{n}").into_bytes(),
|
||||||
|
|
@ -179,100 +261,28 @@ impl Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===formatting===
|
impl IndexableValue {
|
||||||
fn db_type_to_string(type_: DbType) -> String {
|
fn to_value(self) -> Value {
|
||||||
match type_ {
|
match self {
|
||||||
DbType::String => format!("String()"),
|
IndexableValue::String(str) => Value::String(str),
|
||||||
DbType::Int => format!("Int()"),
|
IndexableValue::Int(n) => Value::Int(n),
|
||||||
DbType::Number => format!("Number()"),
|
IndexableValue::Uuid(id) => Value::Uuid(id),
|
||||||
DbType::Uuid => format!("Uuid()"),
|
IndexableValue::Some(indexable_value) => Value::Some(Box::new(indexable_value.to_value())),
|
||||||
DbType::Option(type_) => format!("Option({})", db_type_to_string(*type_)),
|
IndexableValue::None(type_) => Value::None(type_),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn indexable_value_to_string(value: IndexableValue) -> String {
|
fn to_json_key_string(self) -> String {
|
||||||
match value {
|
match self {
|
||||||
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) => format!("Some({})", indexable_value_to_string(*val)),
|
IndexableValue::Some(val) => format!("Some({})", val.to_json_key_string()),
|
||||||
IndexableValue::None(_type_) => "None()".to_string(),
|
IndexableValue::None(_type_) => "None()".to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn value_to_string(value: Value) -> String {
|
fn parse_json_key_string(str: &str) -> Result<Self, 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(')') {
|
if !str.ends_with(')') {
|
||||||
return Err(format!("Invalid IndexableValue: {}", str));
|
return Err(format!("Invalid IndexableValue: {}", str));
|
||||||
}
|
}
|
||||||
|
|
@ -294,56 +304,62 @@ fn parse_indexable_value(str: &str) -> Result<IndexableValue, String> {
|
||||||
Ok(IndexableValue::Uuid(u))
|
Ok(IndexableValue::Uuid(u))
|
||||||
} else if str.starts_with("Some(") {
|
} else if str.starts_with("Some(") {
|
||||||
let s = str[5..str.len() - 1].to_string();
|
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)))
|
Ok(IndexableValue::Some(Box::new(val)))
|
||||||
} else if str.starts_with("None(") {
|
} else if str.starts_with("None(") {
|
||||||
let s = str[5..str.len() - 1].to_string();
|
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_))
|
Ok(IndexableValue::None(type_))
|
||||||
} else {
|
} else {
|
||||||
Err(format!("Invalid IndexableValue: {}", str))
|
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
|
// 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 {
|
||||||
indexable_value_to_string(value)
|
value.to_json_key_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<DbType> for String {
|
impl From<DbType> for String {
|
||||||
fn from(type_: DbType) -> Self {
|
fn from(type_: DbType) -> Self {
|
||||||
db_type_to_string(type_)
|
type_.to_json_key_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<String> for DbType {
|
impl TryFrom<String> for DbType {
|
||||||
type Error = String;
|
type Error = String;
|
||||||
fn try_from(str: String) -> Result<Self, Self::Error> {
|
fn try_from(str: String) -> Result<Self, Self::Error> {
|
||||||
parse_db_type(&str)
|
Self::parse_json_key_string(&str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<String> for IndexableValue {
|
impl TryFrom<String> for IndexableValue {
|
||||||
type Error = String;
|
type Error = String;
|
||||||
fn try_from(str: String) -> Result<Self, Self::Error> {
|
fn try_from(str: String) -> Result<Self, Self::Error> {
|
||||||
parse_indexable_value(&str)
|
Self::parse_json_key_string(&str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Value> for String {
|
impl From<Value> for String {
|
||||||
fn from(value: Value) -> Self {
|
fn from(value: Value) -> Self {
|
||||||
value_to_string(value)
|
value.to_json_key_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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> {
|
||||||
parse_value(&value)
|
Value::parse_json_key_string(&value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue