review: change trait req for entity unwrap* functions to TryFrom<Value> to handle errors
This commit is contained in:
@@ -46,11 +46,11 @@ impl From<Entity> for Product {
|
|||||||
// Set the product's ID from the entity's ID.
|
// Set the product's ID from the entity's ID.
|
||||||
id: value.id.clone(),
|
id: value.id.clone(),
|
||||||
// Unwrap the "name" attribute to get the product's name.
|
// Unwrap the "name" attribute to get the product's name.
|
||||||
name: value.unwrap("name"),
|
name: value.unwrap("name").expect("name is always present"),
|
||||||
// Unwrap the optional "model" attribute to get the product's model.
|
// Unwrap the optional "model" attribute to get the product's model.
|
||||||
model: value.unwrap_opt("model"),
|
model: value.unwrap_opt("model").expect("model is always present"),
|
||||||
// Unwrap the "price" attribute to get the product's price.
|
// Unwrap the "price" attribute to get the product's price.
|
||||||
price: value.unwrap("price"),
|
price: value.unwrap("price").expect("price is always present"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
use crate::*;
|
|
||||||
|
|
||||||
impl From<Value> for bool {
|
|
||||||
fn from(value: Value) -> bool {
|
|
||||||
match value {
|
|
||||||
Value::Bool(value) => value,
|
|
||||||
_ => panic!("Type mismatch"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
11
01.workspace/heave/src/imp/bool_try_from_value.rs
Normal file
11
01.workspace/heave/src/imp/bool_try_from_value.rs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
use crate::*;
|
||||||
|
|
||||||
|
impl TryFrom<Value> for bool {
|
||||||
|
type Error = ();
|
||||||
|
fn try_from(value: Value) -> Result<bool, Self::Error> {
|
||||||
|
match value {
|
||||||
|
Value::Bool(value) => Ok(value),
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
use crate::*;
|
|
||||||
|
|
||||||
impl From<Value> for f64 {
|
|
||||||
fn from(value: Value) -> f64 {
|
|
||||||
match value {
|
|
||||||
Value::Real(value) => value,
|
|
||||||
_ => panic!("Type mismatch"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
11
01.workspace/heave/src/imp/f64_try_from_value.rs
Normal file
11
01.workspace/heave/src/imp/f64_try_from_value.rs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
use crate::*;
|
||||||
|
|
||||||
|
impl TryFrom<Value> for f64 {
|
||||||
|
type Error = ();
|
||||||
|
fn try_from(value: Value) -> Result<f64, Self::Error> {
|
||||||
|
match value {
|
||||||
|
Value::Real(value) => Ok(value),
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
use crate::*;
|
|
||||||
|
|
||||||
impl From<Value> for i32 {
|
|
||||||
fn from(value: Value) -> i32 {
|
|
||||||
match value {
|
|
||||||
Value::SignedInt(value) => value
|
|
||||||
.try_into()
|
|
||||||
.map_err(|_| "Type mismatch".to_string())
|
|
||||||
.unwrap(),
|
|
||||||
_ => panic!("Type mismatch"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
11
01.workspace/heave/src/imp/i32_try_from_value.rs
Normal file
11
01.workspace/heave/src/imp/i32_try_from_value.rs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
use crate::*;
|
||||||
|
|
||||||
|
impl TryFrom<Value> for i32 {
|
||||||
|
type Error = ();
|
||||||
|
fn try_from(value: Value) -> Result<i32, Self::Error> {
|
||||||
|
match value {
|
||||||
|
Value::SignedInt(value) => value.try_into().map_err(|_| ()),
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
use crate::*;
|
|
||||||
|
|
||||||
impl From<Value> for i64 {
|
|
||||||
fn from(value: Value) -> i64 {
|
|
||||||
match value {
|
|
||||||
Value::SignedInt(value) => value,
|
|
||||||
_ => panic!("Type mismatch"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
11
01.workspace/heave/src/imp/i64_try_from_value.rs
Normal file
11
01.workspace/heave/src/imp/i64_try_from_value.rs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
use crate::*;
|
||||||
|
|
||||||
|
impl TryFrom<Value> for i64 {
|
||||||
|
type Error = ();
|
||||||
|
fn try_from(value: Value) -> Result<i64, Self::Error> {
|
||||||
|
match value {
|
||||||
|
Value::SignedInt(value) => Ok(value),
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
pub mod bool_from_value;
|
pub mod bool_try_from_value;
|
||||||
pub mod f64_from_value;
|
pub mod f64_try_from_value;
|
||||||
pub mod i32_from_value;
|
pub mod i32_try_from_value;
|
||||||
pub mod i64_from_value;
|
pub mod i64_try_from_value;
|
||||||
pub mod string_from_value;
|
pub mod string_try_from_value;
|
||||||
pub mod u32_from_value;
|
pub mod u32_try_from_value;
|
||||||
pub mod u64_from_value;
|
pub mod u64_try_from_value;
|
||||||
pub mod value_from_bool;
|
pub mod value_from_bool;
|
||||||
pub mod value_from_f64;
|
pub mod value_from_f64;
|
||||||
pub mod value_from_i32;
|
pub mod value_from_i32;
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
use crate::*;
|
|
||||||
|
|
||||||
impl From<Value> for String {
|
|
||||||
fn from(value: Value) -> String {
|
|
||||||
match value {
|
|
||||||
Value::Text(value) => value,
|
|
||||||
_ => panic!("Type mismatch"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
11
01.workspace/heave/src/imp/string_try_from_value.rs
Normal file
11
01.workspace/heave/src/imp/string_try_from_value.rs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
use crate::*;
|
||||||
|
|
||||||
|
impl TryFrom<Value> for String {
|
||||||
|
type Error = ();
|
||||||
|
fn try_from(value: Value) -> Result<String, Self::Error> {
|
||||||
|
match value {
|
||||||
|
Value::Text(value) => Ok(value),
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
use crate::*;
|
|
||||||
|
|
||||||
impl From<Value> for u32 {
|
|
||||||
fn from(value: Value) -> u32 {
|
|
||||||
match value {
|
|
||||||
Value::UnsignedInt(value) => value
|
|
||||||
.try_into()
|
|
||||||
.map_err(|_| "Type mismatch".to_string())
|
|
||||||
.unwrap(),
|
|
||||||
_ => panic!("Type mismatch"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
11
01.workspace/heave/src/imp/u32_try_from_value.rs
Normal file
11
01.workspace/heave/src/imp/u32_try_from_value.rs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
use crate::*;
|
||||||
|
|
||||||
|
impl TryFrom<Value> for u32 {
|
||||||
|
type Error = ();
|
||||||
|
fn try_from(value: Value) -> Result<u32, Self::Error> {
|
||||||
|
match value {
|
||||||
|
Value::UnsignedInt(value) => value.try_into().map_err(|_| ()),
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
use crate::*;
|
|
||||||
|
|
||||||
impl From<Value> for u64 {
|
|
||||||
fn from(value: Value) -> u64 {
|
|
||||||
match value {
|
|
||||||
Value::UnsignedInt(value) => value,
|
|
||||||
_ => panic!("Type mismatch"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
11
01.workspace/heave/src/imp/u64_try_from_value.rs
Normal file
11
01.workspace/heave/src/imp/u64_try_from_value.rs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
use crate::*;
|
||||||
|
|
||||||
|
impl TryFrom<Value> for u64 {
|
||||||
|
type Error = ();
|
||||||
|
fn try_from(value: Value) -> Result<u64, Self::Error> {
|
||||||
|
match value {
|
||||||
|
Value::UnsignedInt(value) => Ok(value),
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -224,9 +224,11 @@ mod tests {
|
|||||||
fn from(entity: Entity) -> Self {
|
fn from(entity: Entity) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: entity.id.clone(),
|
id: entity.id.clone(),
|
||||||
name: entity.unwrap("name"),
|
name: entity.unwrap("name").expect("name is always present"),
|
||||||
price: entity.unwrap("price"),
|
price: entity.unwrap("price").expect("price is always present"),
|
||||||
in_stock: entity.unwrap("in_stock"),
|
in_stock: entity
|
||||||
|
.unwrap("in_stock")
|
||||||
|
.expect("in_stock is always present"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,9 +101,7 @@ impl Entity {
|
|||||||
|
|
||||||
/// Unwraps an attribute's value into a specified type `T`.
|
/// Unwraps an attribute's value into a specified type `T`.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// This function requires `T` to implement `TryFrom<Value>`.
|
||||||
///
|
|
||||||
/// Panics if the attribute does not exist.
|
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
@@ -111,48 +109,59 @@ impl Entity {
|
|||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// The value of the attribute converted to type `T`.
|
/// A `Result<T, FailedTo>` which is `Ok(T)` if the conversion is successful,
|
||||||
pub fn unwrap<T>(&self, id: &str) -> T
|
/// or `Err(FailedTo::ConvertValue)` if it fails.
|
||||||
|
pub fn unwrap<T>(&self, id: &str) -> Result<T, FailedTo>
|
||||||
where
|
where
|
||||||
T: From<Value>,
|
T: TryFrom<Value>,
|
||||||
{
|
{
|
||||||
self.value_of(id)
|
self.value_of(id)
|
||||||
.map(|value| T::from(value.clone()))
|
.map(|value| T::try_from(value.clone()).map_err(|_| FailedTo::ConvertValue))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unwraps an attribute's value into an `Option<T>`.
|
/// Unwraps an attribute's value into an `Option<T>`.
|
||||||
///
|
///
|
||||||
|
/// This function requires `T` to implement `TryFrom<Value>`.
|
||||||
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `id` - The ID of the attribute to unwrap.
|
/// * `id` - The ID of the attribute to unwrap.
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// An `Option<T>` containing the converted value if the attribute exists, otherwise `None`.
|
/// A `Result<Option<T>, FailedTo>`.
|
||||||
pub fn unwrap_opt<T>(&self, id: &str) -> Option<T>
|
/// - `Ok(Some(T))` if the attribute exists and the conversion is successful.
|
||||||
|
/// - `Ok(None)` if the attribute does not exist.
|
||||||
|
/// - `Err(FailedTo::ConvertValue)` if the attribute exists but the conversion fails.
|
||||||
|
pub fn unwrap_opt<T>(&self, id: &str) -> Result<Option<T>, FailedTo>
|
||||||
where
|
where
|
||||||
T: From<Value>,
|
T: TryFrom<Value>,
|
||||||
{
|
|
||||||
self.value_of(id).map(|value| T::from(value.clone()))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Unwraps an attribute's value, returning a default if it doesn't exist.
|
|
||||||
///
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `id` - The ID of the attribute to unwrap.
|
|
||||||
/// * `default` - The default value to return if the attribute is not found.
|
|
||||||
///
|
|
||||||
/// # Returns
|
|
||||||
///
|
|
||||||
/// The converted value of the attribute or the default value.
|
|
||||||
pub fn unwrap_or<T>(&self, id: &str, default: T) -> T
|
|
||||||
where
|
|
||||||
T: From<Value>,
|
|
||||||
{
|
{
|
||||||
self.value_of(id)
|
self.value_of(id)
|
||||||
.map(|value| T::from(value.clone()))
|
.map(|value| T::try_from(value.clone()).map_err(|_| FailedTo::ConvertValue))
|
||||||
.unwrap_or(default)
|
.transpose()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Unwraps an attribute's value, returning a default value if it doesn't exist or fails to convert.
|
||||||
|
///
|
||||||
|
/// This function requires `T` to implement `TryFrom<Value>`.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `id` - The ID of the attribute to unwrap.
|
||||||
|
/// * `default` - The default value to return if the attribute is not found or conversion fails.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// The converted value of the attribute, or the default value.
|
||||||
|
pub fn unwrap_or<T>(&self, id: &str, default: T) -> Result<T, FailedTo>
|
||||||
|
where
|
||||||
|
T: TryFrom<Value>,
|
||||||
|
{
|
||||||
|
self.value_of(id)
|
||||||
|
.map(|value| T::try_from(value.clone()).map_err(|_| FailedTo::ConvertValue))
|
||||||
|
.transpose()
|
||||||
|
.map(|value| value.unwrap_or(default))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ use crate::*;
|
|||||||
/// Represents the possible failures that can occur in the library.
|
/// Represents the possible failures that can occur in the library.
|
||||||
#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, Hash)]
|
#[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, Hash)]
|
||||||
pub enum FailedTo {
|
pub enum FailedTo {
|
||||||
|
/// Failed to convert from Value to type.
|
||||||
|
ConvertValue,
|
||||||
/// Failed to initialize the database.
|
/// Failed to initialize the database.
|
||||||
InitDatabase,
|
InitDatabase,
|
||||||
/// Failed to load data from the database.
|
/// Failed to load data from the database.
|
||||||
|
|||||||
Reference in New Issue
Block a user