diff --git a/Cargo.toml b/Cargo.toml index 0dae4ad..76fec6c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,12 @@ [package] authors = ["Paul Mason "] build = "build.rs" -categories = ["science","mathematics","data-structures"] +categories = ["science", "mathematics", "data-structures"] description = "Decimal number implementation written in pure Rust suitable for financial and fixed-precision calculations." documentation = "https://docs.rs/rust_decimal/" edition = "2021" -exclude = [ "tests/generated/*" ] -keywords = ["decimal","financial","fixed","precision","number"] +exclude = ["tests/generated/*"] +keywords = ["decimal", "financial", "fixed", "precision", "number"] license = "MIT" name = "rust_decimal" readme = "./README.md" @@ -23,8 +23,7 @@ arbitrary = { default-features = false, optional = true, version = "1.0" } arrayvec = { default-features = false, version = "0.7" } borsh = { default-features = false, features = ["derive", "unstable__schema"], optional = true, version = "1.1.1" } bytes = { default-features = false, optional = true, version = "1.0" } -diesel1 = { default-features = false, optional = true, package = "diesel", version = "1.0" } -diesel2 = { default-features = false, optional = true, package = "diesel", version = "2.1" } +diesel = { default-features = false, optional = true, version = "2.2" } ndarray = { default-features = false, optional = true, version = "0.15.6" } num-traits = { default-features = false, features = ["i128"], version = "0.2" } postgres-types = { default-features = false, optional = true, version = "0.2" } @@ -59,12 +58,10 @@ default = ["serde", "std"] borsh = ["dep:borsh", "std"] c-repr = [] # Force Decimal to be repr(C) -db-diesel-mysql = ["db-diesel1-mysql"] -db-diesel-postgres = ["db-diesel1-postgres"] -db-diesel1-mysql = ["diesel1/mysql", "std"] -db-diesel1-postgres = ["diesel1/postgres", "std"] -db-diesel2-mysql = ["diesel2/mysql", "std"] -db-diesel2-postgres = ["diesel2/postgres", "std"] +db-diesel-mysql = ["diesel/mysql", "std"] +db-diesel-postgres = ["diesel/postgres", "std"] +db-diesel2-mysql = ["db-diesel-mysql"] +db-diesel2-postgres = ["db-diesel-postgres"] db-postgres = ["dep:bytes", "dep:postgres-types", "std"] db-tokio-postgres = ["dep:bytes", "dep:postgres-types", "std"] legacy-ops = [] diff --git a/README.md b/README.md index cf22c16..dcac735 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,23 @@ # Decimal   [![Build Status]][actions] [![Latest Version]][crates.io] [![Docs Badge]][docs] [Build Status]: https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fpaupino%2Frust-decimal%2Fbadge&label=build&logo=none + [actions]: https://actions-badge.atrox.dev/paupino/rust-decimal/goto + [Latest Version]: https://img.shields.io/crates/v/rust-decimal.svg + [crates.io]: https://crates.io/crates/rust-decimal + [Docs Badge]: https://docs.rs/rust_decimal/badge.svg + [docs]: https://docs.rs/rust_decimal -A Decimal number implementation written in pure Rust suitable for financial calculations that require significant integral and fractional digits with no round-off errors. +A Decimal number implementation written in pure Rust suitable for financial calculations that require significant +integral and fractional digits with no round-off errors. -The binary representation consists of a 96 bit integer number, a scaling factor used to specify the decimal fraction and a 1 bit sign. Because of this representation, trailing zeros are preserved and may be exposed when in string form. These can be truncated using the `normalize` or `round_dp` functions. +The binary representation consists of a 96 bit integer number, a scaling factor used to specify the decimal fraction and +a 1 bit sign. Because of this representation, trailing zeros are preserved and may be exposed when in string form. These +can be truncated using the `normalize` or `round_dp` functions. ## Installing @@ -33,7 +41,8 @@ rust_decimal_macros = "1.35" ## Usage -Decimal numbers can be created in a few distinct ways. The easiest and most efficient method of creating a Decimal is to use the procedural macro that can be enabled using the `macros` feature: +Decimal numbers can be created in a few distinct ways. The easiest and most efficient method of creating a Decimal is to +use the procedural macro that can be enabled using the `macros` feature: ```rust // Import the `rust_decimal_macros` crate and use the macro directly from there. @@ -44,7 +53,8 @@ assert_eq!(number, dec!(2.22)); assert_eq!(number.to_string(), "2.22"); ``` -Alternatively you can also use one of the Decimal number convenience functions ([see the docs](https://docs.rs/rust_decimal/) for more details): +Alternatively you can also use one of the Decimal number convenience +functions ([see the docs](https://docs.rs/rust_decimal/) for more details): ```rust // Using the prelude can help importing trait based functions (e.g. core::str::FromStr). @@ -140,31 +150,30 @@ Enables the tokio postgres module allowing for async communication with PostgreS ### `db-diesel-postgres` -Enable `diesel` PostgreSQL support. By default, this enables version `1.4` of `diesel`. If you wish to use the `2.0` -version of `diesel` then you can do so by using the feature `db-diesel2-postgres`. Please note, if both features are -enabled then version 2 will supersede version 1. +Enable [`diesel`](https://diesel.rs) PostgreSQL support. ### `db-diesel-mysql` -Enable `diesel` MySQL support. By default, this enables version `1.4` of `diesel`. If you wish to use the `2.0` -version of `diesel` then you can do so by using the feature `db-diesel2-mysql`. Please note, if both features are -enabled then version 2 will supersede version 1. +Enable [`diesel`](https://diesel.rs) MySQL support. ### `legacy-ops` **Warning:** This is deprecated and will be removed from a future versions. -As of `1.10` the algorithms used to perform basic operations have changed which has benefits of significant speed improvements. +As of `1.10` the algorithms used to perform basic operations have changed which has benefits of significant speed +improvements. To maintain backwards compatibility this can be opted out of by enabling the `legacy-ops` feature. ### `maths` The `maths` feature enables additional complex mathematical functions such as `pow`, `ln`, `enf`, `exp` etc. Documentation detailing the additional functions can be found on the -[`MathematicalOps`](https://docs.rs/rust_decimal/latest/rust_decimal/trait.MathematicalOps.html) trait. +[`MathematicalOps`](https://docs.rs/rust_decimal/latest/rust_decimal/trait.MathematicalOps.html) trait. -Please note that `ln` and `log10` will panic on invalid input with `checked_ln` and `checked_log10` the preferred functions -to curb against this. When the `maths` feature was first developed the library would instead return `0` on invalid input. To re-enable this +Please note that `ln` and `log10` will panic on invalid input with `checked_ln` and `checked_log10` the preferred +functions +to curb against this. When the `maths` feature was first developed the library would instead return `0` on invalid +input. To re-enable this non-panicking behavior, please use the feature: `maths-nopanic`. ### `ndarray` @@ -179,10 +188,13 @@ Enables a [`proptest`](https://github.com/proptest-rs/proptest) strategy to gene Implements `rand::distributions::Distribution` to allow the creation of random instances. -Note: When using `rand::Rng` trait to generate a decimal between a range of two other decimals, the scale of the randomly-generated -decimal will be the same as the scale of the input decimals (or, if the inputs have different scales, the higher of the two). +Note: When using `rand::Rng` trait to generate a decimal between a range of two other decimals, the scale of the +randomly-generated +decimal will be the same as the scale of the input decimals (or, if the inputs have different scales, the higher of the +two). ### `rkyv` + Enables [rkyv](https://github.com/rkyv/rkyv) serialization for `Decimal`. Supports rkyv's safe API when the `rkyv-safe` feature is enabled as well. @@ -196,12 +208,14 @@ Enable `rust-fuzz` support by implementing the `Arbitrary` trait. ### `serde-float` -> **Note:** This feature applies float serialization/deserialization rules as the default method for handling `Decimal` numbers. -See also the `serde-with-*` features for greater flexibility. +> **Note:** This feature applies float serialization/deserialization rules as the default method for handling `Decimal` +> numbers. +> See also the `serde-with-*` features for greater flexibility. Enable this so that JSON serialization of `Decimal` types are sent as a float instead of a string (default). e.g. with this turned on, JSON serialization would output: + ```json { "value": 1.234 @@ -210,8 +224,9 @@ e.g. with this turned on, JSON serialization would output: ### `serde-str` -> **Note:** This feature applies string serialization/deserialization rules as the default method for handling `Decimal` numbers. -See also the `serde-with-*` features for greater flexibility. +> **Note:** This feature applies string serialization/deserialization rules as the default method for handling `Decimal` +> numbers. +> See also the `serde-with-*` features for greater flexibility. This is typically useful for `bincode` or `csv` like implementations. @@ -225,20 +240,23 @@ converting to `f64` _loses_ precision, it's highly recommended that you do NOT e ### `serde-arbitrary-precision` -> **Note:** This feature applies arbitrary serialization/deserialization rules as the default method for handling `Decimal` numbers. -See also the `serde-with-*` features for greater flexibility. +> **Note:** This feature applies arbitrary serialization/deserialization rules as the default method for +> handling `Decimal` numbers. +> See also the `serde-with-*` features for greater flexibility. This is used primarily with `serde_json` and consequently adds it as a "weak dependency". This supports the `arbitrary_precision` feature inside `serde_json` when parsing decimals. This is recommended when parsing "float" looking data as it will prevent data loss. -Please note, this currently serializes numbers in a float like format by default, which can be an unexpected consequence. For greater +Please note, this currently serializes numbers in a float like format by default, which can be an unexpected +consequence. For greater control over the serialization format, please use the `serde-with-arbitrary-precision` feature. ### `serde-with-float` -Enable this to access the module for serializing `Decimal` types to a float. This can be used in `struct` definitions like so: +Enable this to access the module for serializing `Decimal` types to a float. This can be used in `struct` definitions +like so: ```rust #[derive(Serialize, Deserialize)] @@ -247,6 +265,7 @@ pub struct FloatExample { value: Decimal, } ``` + ```rust #[derive(Serialize, Deserialize)] pub struct OptionFloatExample { @@ -256,6 +275,7 @@ pub struct OptionFloatExample { ``` Alternatively, if only the serialization feature is desired (e.g. to keep flexibility while deserialization): + ```rust #[derive(Serialize, Deserialize)] pub struct FloatExample { @@ -266,7 +286,8 @@ pub struct FloatExample { ### `serde-with-str` -Enable this to access the module for serializing `Decimal` types to a `String`. This can be used in `struct` definitions like so: +Enable this to access the module for serializing `Decimal` types to a `String`. This can be used in `struct` definitions +like so: ```rust #[derive(Serialize, Deserialize)] @@ -275,6 +296,7 @@ pub struct StrExample { value: Decimal, } ``` + ```rust #[derive(Serialize, Deserialize)] pub struct OptionStrExample { @@ -283,8 +305,10 @@ pub struct OptionStrExample { } ``` -This feature isn't typically required for serialization however can be useful for deserialization purposes since it does not require +This feature isn't typically required for serialization however can be useful for deserialization purposes since it does +not require a type hint. Consequently, you can force this for just deserialization by: + ```rust #[derive(Serialize, Deserialize)] pub struct StrExample { @@ -295,7 +319,8 @@ pub struct StrExample { ### `serde-with-arbitrary-precision` -Enable this to access the module for deserializing `Decimal` types using the `serde_json/arbitrary_precision` feature. This can be used in `struct` definitions like so: +Enable this to access the module for deserializing `Decimal` types using the `serde_json/arbitrary_precision` feature. +This can be used in `struct` definitions like so: ```rust #[derive(Serialize, Deserialize)] @@ -304,6 +329,7 @@ pub struct ArbitraryExample { value: Decimal, } ``` + ```rust #[derive(Serialize, Deserialize)] pub struct OptionArbitraryExample { @@ -312,8 +338,9 @@ pub struct OptionArbitraryExample { } ``` -An unexpected consequence of this feature is that it will serialize as a float like number. To prevent this, you can +An unexpected consequence of this feature is that it will serialize as a float like number. To prevent this, you can target the struct to only deserialize with the `arbitrary_precision` feature: + ```rust #[derive(Serialize, Deserialize)] pub struct ArbitraryExample { @@ -328,7 +355,8 @@ Please see the `examples` directory for more information regarding `serde_json` ### `std` -Enable `std` library support. This is enabled by default, however in the future will be opt in. For now, to support `no_std` +Enable `std` library support. This is enabled by default, however in the future will be opt in. For now, to +support `no_std` libraries, this crate can be compiled with `--no-default-features`. ## Building @@ -337,31 +365,41 @@ Please refer to the [Build document](BUILD.md) for more information on building ## Minimum Rust Compiler Version -The current _minimum_ compiler version is [`1.60.0`](https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1600-2022-04-07) +The current _minimum_ compiler version +is [`1.60.0`](https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1600-2022-04-07) which was released on `2022-04-07`. -This library maintains support for rust compiler versions that are 4 minor versions away from the current stable rust compiler version. -For example, if the current stable compiler version is `1.50.0` then we will guarantee support up to and including `1.46.0`. +This library maintains support for rust compiler versions that are 4 minor versions away from the current stable rust +compiler version. +For example, if the current stable compiler version is `1.50.0` then we will guarantee support up to and +including `1.46.0`. Of note, we will only update the minimum supported version if and when required. ## Comparison to other Decimal implementations -During the development of this library, there were various design decisions made to ensure that decimal calculations would -be quick, accurate and efficient. Some decisions, however, put limitations on what this library can do and ultimately what -it is suitable for. One such decision was the structure of the internal decimal representation. - -This library uses a mantissa of 96 bits made up of three 32-bit unsigned integers with a fourth 32-bit unsigned integer to represent the scale/sign -(similar to the C and .NET Decimal implementations). -This structure allows us to make use of algorithmic optimizations to implement basic arithmetic; ultimately this gives us the ability -to squeeze out performance and make it one of the fastest implementations available. The downside of this approach however is that +During the development of this library, there were various design decisions made to ensure that decimal calculations +would +be quick, accurate and efficient. Some decisions, however, put limitations on what this library can do and ultimately +what +it is suitable for. One such decision was the structure of the internal decimal representation. + +This library uses a mantissa of 96 bits made up of three 32-bit unsigned integers with a fourth 32-bit unsigned integer +to represent the scale/sign +(similar to the C and .NET Decimal implementations). +This structure allows us to make use of algorithmic optimizations to implement basic arithmetic; ultimately this gives +us the ability +to squeeze out performance and make it one of the fastest implementations available. The downside of this approach +however is that the maximum number of significant digits that can be represented is roughly 28 base-10 digits (29 in some cases). -While this constraint is not an issue for many applications (e.g. when dealing with money), some applications may require a higher number of significant digits to be represented. Fortunately, +While this constraint is not an issue for many applications (e.g. when dealing with money), some applications may +require a higher number of significant digits to be represented. Fortunately, there are alternative implementations that may be worth investigating, such as: * [bigdecimal](https://crates.io/crates/bigdecimal) * [decimal-rs](https://crates.io/crates/decimal-rs) -If you have further questions about the suitability of this library for your project, then feel free to either start a -[discussion](https://github.com/paupino/rust-decimal/discussions) or open an [issue](https://github.com/paupino/rust-decimal/issues) and we'll +If you have further questions about the suitability of this library for your project, then feel free to either start a +[discussion](https://github.com/paupino/rust-decimal/discussions) or open +an [issue](https://github.com/paupino/rust-decimal/issues) and we'll do our best to help. diff --git a/make/tests/db.toml b/make/tests/db.toml index 33f9eb6..4d245b2 100644 --- a/make/tests/db.toml +++ b/make/tests/db.toml @@ -8,8 +8,7 @@ dependencies = [ dependencies = [ "test-db-postgres", "test-db-tokio-postgres", - "test-db-diesel1-postgres", - "test-db-diesel2-postgres" + "test-db-diesel-postgres" ] # DB Tests require cleaning beforehand to avoid target conflicts @@ -31,46 +30,27 @@ args = ["test", "--workspace", "--tests", "--features=db-tokio-postgres", "postg [tasks.test-db-mysql-all] dependencies = [ - "test-db-diesel1-mysql", - "test-db-diesel2-mysql", + "test-db-diesel-mysql", ] [tasks.test-db-diesel] dependencies = [ - "test-db-diesel1-mysql", - "test-db-diesel1-postgres", - "test-db-diesel2-mysql", - "test-db-diesel2-postgres", + "test-db-diesel-mysql", + "test-db-diesel-postgres", ] -[tasks.clean-db-diesel1-mysql] +[tasks.clean-db-diesel-mysql] alias = "clean" -[tasks.test-db-diesel1-mysql] -dependencies = ["clean-db-diesel1-mysql"] +[tasks.test-db-diesel-mysql] +dependencies = ["clean-db-diesel-mysql"] command = "cargo" -args = ["test", "--workspace", "--tests", "--features=db-diesel1-mysql", "mysql", "--", "--skip", "generated"] +args = ["test", "--workspace", "--tests", "--features=db-diesel-mysql", "mysql", "--", "--skip", "generated"] -[tasks.clean-db-diesel2-mysql] +[tasks.clean-db-diesel-postgres] alias = "clean" -[tasks.test-db-diesel2-mysql] -dependencies = ["clean-db-diesel2-mysql"] +[tasks.test-db-diesel-postgres] +dependencies = ["clean-db-diesel-postgres"] command = "cargo" -args = ["test", "--workspace", "--tests", "--features=db-diesel2-mysql", "mysql", "--", "--skip", "generated"] - -[tasks.clean-db-diesel1-postgres] -alias = "clean" - -[tasks.test-db-diesel1-postgres] -dependencies = ["clean-db-diesel1-postgres"] -command = "cargo" -args = ["test", "--workspace", "--tests", "--features=db-diesel1-postgres", "postgres", "--", "--skip", "generated"] - -[tasks.clean-db-diesel2-postgres] -alias = "clean" - -[tasks.test-db-diesel2-postgres] -dependencies = ["clean-db-diesel2-postgres"] -command = "cargo" -args = ["test", "--workspace", "--tests", "--features=db-diesel2-postgres", "postgres", "--", "--skip", "generated"] +args = ["test", "--workspace", "--tests", "--features=db-diesel-postgres", "postgres", "--", "--skip", "generated"] diff --git a/src/decimal.rs b/src/decimal.rs index 20dd9c0..2388748 100644 --- a/src/decimal.rs +++ b/src/decimal.rs @@ -14,12 +14,8 @@ use core::{ }; // Diesel configuration -#[cfg(feature = "diesel2")] -use diesel::deserialize::FromSqlRow; -#[cfg(feature = "diesel2")] -use diesel::expression::AsExpression; -#[cfg(any(feature = "diesel1", feature = "diesel2"))] -use diesel::sql_types::Numeric; +#[cfg(feature = "diesel")] +use diesel::{deserialize::FromSqlRow, expression::AsExpression, sql_types::Numeric}; #[allow(unused_imports)] // It's not actually dead code below, but the compiler thinks it is. #[cfg(not(feature = "std"))] @@ -103,12 +99,7 @@ pub struct UnpackedDecimal { /// where m is an integer such that -296 < m < 296, and e is an integer /// between 0 and 28 inclusive. #[derive(Clone, Copy)] -#[cfg_attr( - all(feature = "diesel1", not(feature = "diesel2")), - derive(FromSqlRow, AsExpression), - sql_type = "Numeric" -)] -#[cfg_attr(feature = "diesel2", derive(FromSqlRow, AsExpression), diesel(sql_type = Numeric))] +#[cfg_attr(feature = "diesel", derive(FromSqlRow, AsExpression), diesel(sql_type = Numeric))] #[cfg_attr(feature = "c-repr", repr(C))] #[cfg_attr( feature = "borsh", diff --git a/src/lib.rs b/src/lib.rs index d49db64..45282f2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,13 +18,12 @@ mod arithmetic_impls; mod fuzz; #[cfg(feature = "maths")] mod maths; -#[cfg(any(feature = "db-diesel1-mysql", feature = "db-diesel2-mysql"))] +#[cfg(feature = "db-diesel-mysql")] mod mysql; #[cfg(any( feature = "db-tokio-postgres", feature = "db-postgres", - feature = "db-diesel1-postgres", - feature = "db-diesel2-postgres", + feature = "db-diesel-postgres", ))] mod postgres; #[cfg(feature = "proptest")] @@ -72,12 +71,8 @@ pub mod prelude { // pub use rust_decimal_macros::dec; } -#[cfg(all(feature = "diesel1", not(feature = "diesel2")))] -#[macro_use] -extern crate diesel1 as diesel; - -#[cfg(feature = "diesel2")] -extern crate diesel2 as diesel; +#[cfg(feature = "diesel")] +extern crate diesel; /// Shortcut for `core::result::Result`. Useful to distinguish /// between `rust_decimal` and `std` types. diff --git a/src/mysql.rs b/src/mysql.rs index 6dc0db2..0996890 100644 --- a/src/mysql.rs +++ b/src/mysql.rs @@ -8,33 +8,14 @@ use diesel::{ use std::io::Write; use std::str::FromStr; -#[cfg(all(feature = "diesel1", not(feature = "diesel2")))] -impl ToSql for Decimal { - fn to_sql(&self, out: &mut Output) -> serialize::Result { - write!(out, "{}", *self).map(|_| IsNull::No).map_err(|e| e.into()) - } -} - -#[cfg(feature = "diesel2")] +#[cfg(feature = "diesel")] impl ToSql for Decimal { fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Mysql>) -> serialize::Result { write!(out, "{}", *self).map(|_| IsNull::No).map_err(|e| e.into()) } } -#[cfg(all(feature = "diesel1", not(feature = "diesel2")))] -impl FromSql for Decimal { - fn from_sql(numeric: Option<&[u8]>) -> deserialize::Result { - // From what I can ascertain, MySQL simply reads from a string format for the Decimal type. - // Explicitly, it looks like it is length followed by the string. Regardless, we can leverage - // internal types. - let bytes = numeric.ok_or("Invalid decimal")?; - let s = std::str::from_utf8(bytes)?; - Decimal::from_str(s).map_err(|e| e.into()) - } -} - -#[cfg(feature = "diesel2")] +#[cfg(feature = "diesel")] impl FromSql for Decimal { fn from_sql(numeric: diesel::mysql::MysqlValue) -> deserialize::Result { // From what I can ascertain, MySQL simply reads from a string format for the Decimal type. @@ -48,11 +29,6 @@ impl FromSql for Decimal { #[cfg(test)] mod tests { use super::*; - use diesel::deserialize::QueryableByName; - use diesel::prelude::*; - use diesel::row::NamedRow; - use diesel::sql_query; - use diesel::sql_types::Text; struct Test { value: Decimal, @@ -95,81 +71,14 @@ mod tests { "mysql://root@127.0.0.1/mysql".to_string() } - #[cfg(all(feature = "diesel1", not(feature = "diesel2")))] - mod diesel1 { - use super::*; - - impl QueryableByName for Test { - fn build>(row: &R) -> deserialize::Result { - let value = row.get("value")?; - Ok(Test { value }) - } - } - - impl QueryableByName for NullableTest { - fn build>(row: &R) -> deserialize::Result { - let value = row.get("value")?; - Ok(NullableTest { value }) - } - } - - #[test] - fn test_null() { - let connection = diesel::MysqlConnection::establish(&get_mysql_url()).expect("Establish connection"); - - // Test NULL - let items: Vec = sql_query("SELECT CAST(NULL AS DECIMAL) AS value") - .load(&connection) - .expect("Unable to query value"); - let result = items.first().unwrap().value; - assert_eq!(None, result); - } - - #[test] - fn read_numeric_type() { - let connection = diesel::MysqlConnection::establish(&get_mysql_url()).expect("Establish connection"); - for &(precision, scale, sent, expected) in TEST_DECIMALS.iter() { - let items: Vec = sql_query(format!( - "SELECT CAST('{}' AS DECIMAL({}, {})) AS value", - sent, precision, scale - )) - .load(&connection) - .expect("Unable to query value"); - assert_eq!( - expected, - items.first().unwrap().value.to_string(), - "DECIMAL({}, {}) sent: {}", - precision, - scale, - sent - ); - } - } - - #[test] - fn write_numeric_type() { - let connection = diesel::MysqlConnection::establish(&get_mysql_url()).expect("Establish connection"); - for &(precision, scale, sent, expected) in TEST_DECIMALS.iter() { - let items: Vec = - sql_query(format!("SELECT CAST(? AS DECIMAL({}, {})) AS value", precision, scale)) - .bind::(sent) - .load(&connection) - .expect("Unable to query value"); - assert_eq!( - expected, - items.first().unwrap().value.to_string(), - "DECIMAL({}, {}) sent: {}", - precision, - scale, - sent - ); - } - } - } - - #[cfg(feature = "diesel2")] - mod diesel2 { + #[cfg(feature = "diesel")] + mod diesel_tests { use super::*; + use diesel::deserialize::QueryableByName; + use diesel::prelude::*; + use diesel::row::NamedRow; + use diesel::sql_query; + use diesel::sql_types::Text; impl QueryableByName for Test { fn build<'a>(row: &impl NamedRow<'a, Mysql>) -> deserialize::Result { diff --git a/src/postgres.rs b/src/postgres.rs index 0930e59..8c740fc 100644 --- a/src/postgres.rs +++ b/src/postgres.rs @@ -1,7 +1,7 @@ // Shared mod common; -#[cfg(any(feature = "db-diesel1-postgres", feature = "db-diesel2-postgres"))] +#[cfg(feature = "db-diesel-postgres")] mod diesel; #[cfg(any(feature = "db-postgres", feature = "db-tokio-postgres"))] diff --git a/src/postgres/diesel.rs b/src/postgres/diesel.rs index d523ad1..eb71242 100644 --- a/src/postgres/diesel.rs +++ b/src/postgres/diesel.rs @@ -70,15 +70,7 @@ impl From for PgNumeric { } } -#[cfg(all(feature = "diesel1", not(feature = "diesel2")))] -impl ToSql for Decimal { - fn to_sql(&self, out: &mut Output) -> serialize::Result { - let numeric = PgNumeric::from(self); - ToSql::::to_sql(&numeric, out) - } -} - -#[cfg(feature = "diesel2")] +#[cfg(feature = "diesel")] impl ToSql for Decimal { fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Pg>) -> serialize::Result { let numeric = PgNumeric::from(self); @@ -86,14 +78,7 @@ impl ToSql for Decimal { } } -#[cfg(all(feature = "diesel1", not(feature = "diesel2")))] -impl FromSql for Decimal { - fn from_sql(numeric: Option<&[u8]>) -> deserialize::Result { - PgNumeric::from_sql(numeric)?.try_into() - } -} - -#[cfg(feature = "diesel2")] +#[cfg(feature = "diesel")] impl FromSql for Decimal { fn from_sql(numeric: diesel::pg::PgValue) -> deserialize::Result { PgNumeric::from_sql(numeric)?.try_into()