diff --git a/Cargo.toml b/Cargo.toml index 4752836a7..ccbcdead8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,10 +2,6 @@ members = [ "codegen", "postgres", - "postgres-derive", - "postgres-derive-test", - "postgres-native-tls", - "postgres-openssl", "postgres-protocol", "postgres-types", "tokio-postgres", diff --git a/postgres-derive-test/Cargo.toml b/postgres-derive-test/Cargo.toml deleted file mode 100644 index 24fd1614f..000000000 --- a/postgres-derive-test/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "postgres-derive-test" -version = "0.1.0" -authors = ["Steven Fackler "] -edition = "2018" - -[dev-dependencies] -trybuild = "1.0" - -postgres-types = { path = "../postgres-types", features = ["derive"] } -postgres = { path = "../postgres" } diff --git a/postgres-derive-test/src/compile-fail/invalid-transparent.rs b/postgres-derive-test/src/compile-fail/invalid-transparent.rs deleted file mode 100644 index 43bd48266..000000000 --- a/postgres-derive-test/src/compile-fail/invalid-transparent.rs +++ /dev/null @@ -1,35 +0,0 @@ -use postgres_types::{FromSql, ToSql}; - -#[derive(ToSql, Debug)] -#[postgres(transparent)] -struct ToSqlTransparentStruct { - a: i32 -} - -#[derive(FromSql, Debug)] -#[postgres(transparent)] -struct FromSqlTransparentStruct { - a: i32 -} - -#[derive(ToSql, Debug)] -#[postgres(transparent)] -enum ToSqlTransparentEnum { - Foo -} - -#[derive(FromSql, Debug)] -#[postgres(transparent)] -enum FromSqlTransparentEnum { - Foo -} - -#[derive(ToSql, Debug)] -#[postgres(transparent)] -struct ToSqlTransparentTwoFieldTupleStruct(i32, i32); - -#[derive(FromSql, Debug)] -#[postgres(transparent)] -struct FromSqlTransparentTwoFieldTupleStruct(i32, i32); - -fn main() {} diff --git a/postgres-derive-test/src/compile-fail/invalid-transparent.stderr b/postgres-derive-test/src/compile-fail/invalid-transparent.stderr deleted file mode 100644 index 42e49f874..000000000 --- a/postgres-derive-test/src/compile-fail/invalid-transparent.stderr +++ /dev/null @@ -1,49 +0,0 @@ -error: #[postgres(transparent)] may only be applied to single field tuple structs - --> src/compile-fail/invalid-transparent.rs:4:1 - | -4 | / #[postgres(transparent)] -5 | | struct ToSqlTransparentStruct { -6 | | a: i32 -7 | | } - | |_^ - -error: #[postgres(transparent)] may only be applied to single field tuple structs - --> src/compile-fail/invalid-transparent.rs:10:1 - | -10 | / #[postgres(transparent)] -11 | | struct FromSqlTransparentStruct { -12 | | a: i32 -13 | | } - | |_^ - -error: #[postgres(transparent)] may only be applied to single field tuple structs - --> src/compile-fail/invalid-transparent.rs:16:1 - | -16 | / #[postgres(transparent)] -17 | | enum ToSqlTransparentEnum { -18 | | Foo -19 | | } - | |_^ - -error: #[postgres(transparent)] may only be applied to single field tuple structs - --> src/compile-fail/invalid-transparent.rs:22:1 - | -22 | / #[postgres(transparent)] -23 | | enum FromSqlTransparentEnum { -24 | | Foo -25 | | } - | |_^ - -error: #[postgres(transparent)] may only be applied to single field tuple structs - --> src/compile-fail/invalid-transparent.rs:28:1 - | -28 | / #[postgres(transparent)] -29 | | struct ToSqlTransparentTwoFieldTupleStruct(i32, i32); - | |_____________________________________________________^ - -error: #[postgres(transparent)] may only be applied to single field tuple structs - --> src/compile-fail/invalid-transparent.rs:32:1 - | -32 | / #[postgres(transparent)] -33 | | struct FromSqlTransparentTwoFieldTupleStruct(i32, i32); - | |_______________________________________________________^ diff --git a/postgres-derive-test/src/compile-fail/invalid-types.rs b/postgres-derive-test/src/compile-fail/invalid-types.rs deleted file mode 100644 index ef41ac820..000000000 --- a/postgres-derive-test/src/compile-fail/invalid-types.rs +++ /dev/null @@ -1,25 +0,0 @@ -use postgres_types::{FromSql, ToSql}; - -#[derive(ToSql)] -struct ToSqlUnit; - -#[derive(FromSql)] -struct FromSqlUnit; - -#[derive(ToSql)] -struct ToSqlTuple(i32, i32); - -#[derive(FromSql)] -struct FromSqlTuple(i32, i32); - -#[derive(ToSql)] -enum ToSqlEnum { - Foo(i32), -} - -#[derive(FromSql)] -enum FromSqlEnum { - Foo(i32), -} - -fn main() {} diff --git a/postgres-derive-test/src/compile-fail/invalid-types.stderr b/postgres-derive-test/src/compile-fail/invalid-types.stderr deleted file mode 100644 index 9b563d58b..000000000 --- a/postgres-derive-test/src/compile-fail/invalid-types.stderr +++ /dev/null @@ -1,35 +0,0 @@ -error: #[derive(ToSql)] may only be applied to structs, single field tuple structs, and enums - --> $DIR/invalid-types.rs:4:1 - | -4 | struct ToSqlUnit; - | ^^^^^^^^^^^^^^^^^ - -error: #[derive(FromSql)] may only be applied to structs, single field tuple structs, and enums - --> $DIR/invalid-types.rs:7:1 - | -7 | struct FromSqlUnit; - | ^^^^^^^^^^^^^^^^^^^ - -error: #[derive(ToSql)] may only be applied to structs, single field tuple structs, and enums - --> $DIR/invalid-types.rs:10:1 - | -10 | struct ToSqlTuple(i32, i32); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: #[derive(FromSql)] may only be applied to structs, single field tuple structs, and enums - --> $DIR/invalid-types.rs:13:1 - | -13 | struct FromSqlTuple(i32, i32); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: non-C-like enums are not supported - --> $DIR/invalid-types.rs:17:5 - | -17 | Foo(i32), - | ^^^^^^^^ - -error: non-C-like enums are not supported - --> $DIR/invalid-types.rs:22:5 - | -22 | Foo(i32), - | ^^^^^^^^ diff --git a/postgres-derive-test/src/compile-fail/unknown-override.rs b/postgres-derive-test/src/compile-fail/unknown-override.rs deleted file mode 100644 index e4fffd540..000000000 --- a/postgres-derive-test/src/compile-fail/unknown-override.rs +++ /dev/null @@ -1,15 +0,0 @@ -use postgres_types::{FromSql, ToSql}; - -#[derive(FromSql)] -#[postgres(foo = "bar")] -struct Foo { - a: i32, -} - -#[derive(ToSql)] -#[postgres(foo = "bar")] -struct Bar { - a: i32, -} - -fn main() {} diff --git a/postgres-derive-test/src/compile-fail/unknown-override.stderr b/postgres-derive-test/src/compile-fail/unknown-override.stderr deleted file mode 100644 index b7719e3c2..000000000 --- a/postgres-derive-test/src/compile-fail/unknown-override.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: unknown override - --> $DIR/unknown-override.rs:4:12 - | -4 | #[postgres(foo = "bar")] - | ^^^ - -error: unknown override - --> $DIR/unknown-override.rs:10:12 - | -10 | #[postgres(foo = "bar")] - | ^^^ diff --git a/postgres-derive-test/src/composites.rs b/postgres-derive-test/src/composites.rs deleted file mode 100644 index a1b76345f..000000000 --- a/postgres-derive-test/src/composites.rs +++ /dev/null @@ -1,305 +0,0 @@ -use crate::{test_type, test_type_asymmetric}; -use postgres::{Client, NoTls}; -use postgres_types::{FromSql, ToSql, WrongType}; -use std::error::Error; - -#[test] -fn defaults() { - #[derive(FromSql, ToSql, Debug, PartialEq)] - struct InventoryItem { - name: String, - supplier_id: i32, - price: Option, - } - - let mut conn = Client::connect("user=postgres host=localhost port=5433", NoTls).unwrap(); - conn.batch_execute( - "CREATE TYPE pg_temp.\"InventoryItem\" AS ( - name TEXT, - supplier_id INT, - price DOUBLE PRECISION - );", - ) - .unwrap(); - - let item = InventoryItem { - name: "foobar".to_owned(), - supplier_id: 100, - price: Some(15.50), - }; - - let item_null = InventoryItem { - name: "foobar".to_owned(), - supplier_id: 100, - price: None, - }; - - test_type( - &mut conn, - "\"InventoryItem\"", - &[ - (item, "ROW('foobar', 100, 15.50)"), - (item_null, "ROW('foobar', 100, NULL)"), - ], - ); -} - -#[test] -fn name_overrides() { - #[derive(FromSql, ToSql, Debug, PartialEq)] - #[postgres(name = "inventory_item")] - struct InventoryItem { - #[postgres(name = "name")] - _name: String, - #[postgres(name = "supplier_id")] - _supplier_id: i32, - #[postgres(name = "price")] - _price: Option, - } - - let mut conn = Client::connect("user=postgres host=localhost port=5433", NoTls).unwrap(); - conn.batch_execute( - "CREATE TYPE pg_temp.inventory_item AS ( - name TEXT, - supplier_id INT, - price DOUBLE PRECISION - );", - ) - .unwrap(); - - let item = InventoryItem { - _name: "foobar".to_owned(), - _supplier_id: 100, - _price: Some(15.50), - }; - - let item_null = InventoryItem { - _name: "foobar".to_owned(), - _supplier_id: 100, - _price: None, - }; - - test_type( - &mut conn, - "inventory_item", - &[ - (item, "ROW('foobar', 100, 15.50)"), - (item_null, "ROW('foobar', 100, NULL)"), - ], - ); -} - -#[test] -fn wrong_name() { - #[derive(FromSql, ToSql, Debug, PartialEq)] - struct InventoryItem { - name: String, - supplier_id: i32, - price: Option, - } - - let mut conn = Client::connect("user=postgres host=localhost port=5433", NoTls).unwrap(); - conn.batch_execute( - "CREATE TYPE pg_temp.inventory_item AS ( - name TEXT, - supplier_id INT, - price DOUBLE PRECISION - );", - ) - .unwrap(); - - let item = InventoryItem { - name: "foobar".to_owned(), - supplier_id: 100, - price: Some(15.50), - }; - - let err = conn - .execute("SELECT $1::inventory_item", &[&item]) - .unwrap_err(); - assert!(err.source().unwrap().is::()); -} - -#[test] -fn extra_field() { - #[derive(FromSql, ToSql, Debug, PartialEq)] - #[postgres(name = "inventory_item")] - struct InventoryItem { - name: String, - supplier_id: i32, - price: Option, - foo: i32, - } - - let mut conn = Client::connect("user=postgres host=localhost port=5433", NoTls).unwrap(); - conn.batch_execute( - "CREATE TYPE pg_temp.inventory_item AS ( - name TEXT, - supplier_id INT, - price DOUBLE PRECISION - );", - ) - .unwrap(); - - let item = InventoryItem { - name: "foobar".to_owned(), - supplier_id: 100, - price: Some(15.50), - foo: 0, - }; - - let err = conn - .execute("SELECT $1::inventory_item", &[&item]) - .unwrap_err(); - assert!(err.source().unwrap().is::()); -} - -#[test] -fn missing_field() { - #[derive(FromSql, ToSql, Debug, PartialEq)] - #[postgres(name = "inventory_item")] - struct InventoryItem { - name: String, - supplier_id: i32, - } - - let mut conn = Client::connect("user=postgres host=localhost port=5433", NoTls).unwrap(); - conn.batch_execute( - "CREATE TYPE pg_temp.inventory_item AS ( - name TEXT, - supplier_id INT, - price DOUBLE PRECISION - );", - ) - .unwrap(); - - let item = InventoryItem { - name: "foobar".to_owned(), - supplier_id: 100, - }; - - let err = conn - .execute("SELECT $1::inventory_item", &[&item]) - .unwrap_err(); - assert!(err.source().unwrap().is::()); -} - -#[test] -fn wrong_type() { - #[derive(FromSql, ToSql, Debug, PartialEq)] - #[postgres(name = "inventory_item")] - struct InventoryItem { - name: String, - supplier_id: i32, - price: i32, - } - - let mut conn = Client::connect("user=postgres host=localhost port=5433", NoTls).unwrap(); - conn.batch_execute( - "CREATE TYPE pg_temp.inventory_item AS ( - name TEXT, - supplier_id INT, - price DOUBLE PRECISION - );", - ) - .unwrap(); - - let item = InventoryItem { - name: "foobar".to_owned(), - supplier_id: 100, - price: 0, - }; - - let err = conn - .execute("SELECT $1::inventory_item", &[&item]) - .unwrap_err(); - assert!(err.source().unwrap().is::()); -} - -#[test] -fn raw_ident_field() { - #[derive(FromSql, ToSql, Debug, PartialEq)] - #[postgres(name = "inventory_item")] - struct InventoryItem { - r#type: String, - } - - let mut conn = Client::connect("user=postgres host=localhost port=5433", NoTls).unwrap(); - conn.batch_execute( - "CREATE TYPE pg_temp.inventory_item AS ( - type TEXT - )", - ) - .unwrap(); - - let item = InventoryItem { - r#type: "foo".to_owned(), - }; - - test_type(&mut conn, "inventory_item", &[(item, "ROW('foo')")]); -} - -#[test] -fn generics() { - #[derive(FromSql, Debug, PartialEq)] - struct InventoryItem - where - U: Clone, - { - name: String, - supplier_id: T, - price: Option, - } - - // doesn't make sense to implement derived FromSql on a type with borrows - #[derive(ToSql, Debug, PartialEq)] - #[postgres(name = "InventoryItem")] - struct InventoryItemRef<'a, T: 'a + Clone, U> - where - U: 'a + Clone, - { - name: &'a str, - supplier_id: &'a T, - price: Option<&'a U>, - } - - const NAME: &str = "foobar"; - const SUPPLIER_ID: i32 = 100; - const PRICE: f64 = 15.50; - - let mut conn = Client::connect("user=postgres host=localhost port=5433", NoTls).unwrap(); - conn.batch_execute( - "CREATE TYPE pg_temp.\"InventoryItem\" AS ( - name TEXT, - supplier_id INT, - price DOUBLE PRECISION - );", - ) - .unwrap(); - - let item = InventoryItemRef { - name: NAME, - supplier_id: &SUPPLIER_ID, - price: Some(&PRICE), - }; - - let item_null = InventoryItemRef { - name: NAME, - supplier_id: &SUPPLIER_ID, - price: None, - }; - - test_type_asymmetric( - &mut conn, - "\"InventoryItem\"", - &[ - (item, "ROW('foobar', 100, 15.50)"), - (item_null, "ROW('foobar', 100, NULL)"), - ], - |t: &InventoryItemRef, f: &InventoryItem| { - t.name == f.name.as_str() - && t.supplier_id == &f.supplier_id - && t.price == f.price.as_ref() - }, - ); -} diff --git a/postgres-derive-test/src/domains.rs b/postgres-derive-test/src/domains.rs deleted file mode 100644 index 25674f75e..000000000 --- a/postgres-derive-test/src/domains.rs +++ /dev/null @@ -1,121 +0,0 @@ -use crate::test_type; -use postgres::{Client, NoTls}; -use postgres_types::{FromSql, ToSql, WrongType}; -use std::error::Error; - -#[test] -fn defaults() { - #[derive(FromSql, ToSql, Debug, PartialEq)] - struct SessionId(Vec); - - let mut conn = Client::connect("user=postgres host=localhost port=5433", NoTls).unwrap(); - conn.execute( - "CREATE DOMAIN pg_temp.\"SessionId\" AS bytea CHECK(octet_length(VALUE) = 16);", - &[], - ) - .unwrap(); - - test_type( - &mut conn, - "\"SessionId\"", - &[( - SessionId(b"0123456789abcdef".to_vec()), - "'0123456789abcdef'", - )], - ); -} - -#[test] -fn name_overrides() { - #[derive(FromSql, ToSql, Debug, PartialEq)] - #[postgres(name = "session_id")] - struct SessionId(Vec); - - let mut conn = Client::connect("user=postgres host=localhost port=5433", NoTls).unwrap(); - conn.execute( - "CREATE DOMAIN pg_temp.session_id AS bytea CHECK(octet_length(VALUE) = 16);", - &[], - ) - .unwrap(); - - test_type( - &mut conn, - "session_id", - &[( - SessionId(b"0123456789abcdef".to_vec()), - "'0123456789abcdef'", - )], - ); -} - -#[test] -fn wrong_name() { - #[derive(FromSql, ToSql, Debug, PartialEq)] - struct SessionId(Vec); - - let mut conn = Client::connect("user=postgres host=localhost port=5433", NoTls).unwrap(); - conn.execute( - "CREATE DOMAIN pg_temp.session_id AS bytea CHECK(octet_length(VALUE) = 16);", - &[], - ) - .unwrap(); - - let err = conn - .execute("SELECT $1::session_id", &[&SessionId(vec![])]) - .unwrap_err(); - assert!(err.source().unwrap().is::()); -} - -#[test] -fn wrong_type() { - #[derive(FromSql, ToSql, Debug, PartialEq)] - #[postgres(name = "session_id")] - struct SessionId(i32); - - let mut conn = Client::connect("user=postgres host=localhost port=5433", NoTls).unwrap(); - conn.execute( - "CREATE DOMAIN pg_temp.session_id AS bytea CHECK(octet_length(VALUE) = 16);", - &[], - ) - .unwrap(); - - let err = conn - .execute("SELECT $1::session_id", &[&SessionId(0)]) - .unwrap_err(); - assert!(err.source().unwrap().is::()); -} - -#[test] -fn domain_in_composite() { - #[derive(FromSql, ToSql, Debug, PartialEq)] - #[postgres(name = "domain")] - struct Domain(String); - - #[derive(FromSql, ToSql, Debug, PartialEq)] - #[postgres(name = "composite")] - struct Composite { - domain: Domain, - } - - let mut conn = Client::connect("user=postgres host=localhost port=5433", NoTls).unwrap(); - conn.batch_execute( - " - CREATE DOMAIN pg_temp.domain AS TEXT;\ - CREATE TYPE pg_temp.composite AS ( - domain domain - ); - ", - ) - .unwrap(); - - test_type( - &mut conn, - "composite", - &[( - Composite { - domain: Domain("hello".to_string()), - }, - "ROW('hello')", - )], - ); -} diff --git a/postgres-derive-test/src/enums.rs b/postgres-derive-test/src/enums.rs deleted file mode 100644 index a7039ca05..000000000 --- a/postgres-derive-test/src/enums.rs +++ /dev/null @@ -1,104 +0,0 @@ -use crate::test_type; -use postgres::{Client, NoTls}; -use postgres_types::{FromSql, ToSql, WrongType}; -use std::error::Error; - -#[test] -fn defaults() { - #[derive(Debug, ToSql, FromSql, PartialEq)] - enum Foo { - Bar, - Baz, - } - - let mut conn = Client::connect("user=postgres host=localhost port=5433", NoTls).unwrap(); - conn.execute("CREATE TYPE pg_temp.\"Foo\" AS ENUM ('Bar', 'Baz')", &[]) - .unwrap(); - - test_type( - &mut conn, - "\"Foo\"", - &[(Foo::Bar, "'Bar'"), (Foo::Baz, "'Baz'")], - ); -} - -#[test] -fn name_overrides() { - #[derive(Debug, ToSql, FromSql, PartialEq)] - #[postgres(name = "mood")] - enum Mood { - #[postgres(name = "sad")] - Sad, - #[postgres(name = "ok")] - Ok, - #[postgres(name = "happy")] - Happy, - } - - let mut conn = Client::connect("user=postgres host=localhost port=5433", NoTls).unwrap(); - conn.execute( - "CREATE TYPE pg_temp.mood AS ENUM ('sad', 'ok', 'happy')", - &[], - ) - .unwrap(); - - test_type( - &mut conn, - "mood", - &[ - (Mood::Sad, "'sad'"), - (Mood::Ok, "'ok'"), - (Mood::Happy, "'happy'"), - ], - ); -} - -#[test] -fn wrong_name() { - #[derive(Debug, ToSql, FromSql, PartialEq)] - enum Foo { - Bar, - Baz, - } - - let mut conn = Client::connect("user=postgres host=localhost port=5433", NoTls).unwrap(); - conn.execute("CREATE TYPE pg_temp.foo AS ENUM ('Bar', 'Baz')", &[]) - .unwrap(); - - let err = conn.execute("SELECT $1::foo", &[&Foo::Bar]).unwrap_err(); - assert!(err.source().unwrap().is::()); -} - -#[test] -fn extra_variant() { - #[derive(Debug, ToSql, FromSql, PartialEq)] - #[postgres(name = "foo")] - enum Foo { - Bar, - Baz, - Buz, - } - - let mut conn = Client::connect("user=postgres host=localhost port=5433", NoTls).unwrap(); - conn.execute("CREATE TYPE pg_temp.foo AS ENUM ('Bar', 'Baz')", &[]) - .unwrap(); - - let err = conn.execute("SELECT $1::foo", &[&Foo::Bar]).unwrap_err(); - assert!(err.source().unwrap().is::()); -} - -#[test] -fn missing_variant() { - #[derive(Debug, ToSql, FromSql, PartialEq)] - #[postgres(name = "foo")] - enum Foo { - Bar, - } - - let mut conn = Client::connect("user=postgres host=localhost port=5433", NoTls).unwrap(); - conn.execute("CREATE TYPE pg_temp.foo AS ENUM ('Bar', 'Baz')", &[]) - .unwrap(); - - let err = conn.execute("SELECT $1::foo", &[&Foo::Bar]).unwrap_err(); - assert!(err.source().unwrap().is::()); -} diff --git a/postgres-derive-test/src/lib.rs b/postgres-derive-test/src/lib.rs deleted file mode 100644 index f0534f32c..000000000 --- a/postgres-derive-test/src/lib.rs +++ /dev/null @@ -1,57 +0,0 @@ -#![cfg(test)] - -use postgres::Client; -use postgres_types::{FromSqlOwned, ToSql}; -use std::fmt; - -mod composites; -mod domains; -mod enums; -mod transparent; - -pub fn test_type(conn: &mut Client, sql_type: &str, checks: &[(T, S)]) -where - T: PartialEq + FromSqlOwned + ToSql + Sync, - S: fmt::Display, -{ - for (val, repr) in checks.iter() { - let stmt = conn - .prepare(&format!("SELECT {}::{}", *repr, sql_type)) - .unwrap(); - let result = conn.query_one(&stmt, &[]).unwrap().get(0); - assert_eq!(val, &result); - - let stmt = conn.prepare(&format!("SELECT $1::{}", sql_type)).unwrap(); - let result = conn.query_one(&stmt, &[val]).unwrap().get(0); - assert_eq!(val, &result); - } -} - -pub fn test_type_asymmetric( - conn: &mut Client, - sql_type: &str, - checks: &[(T, S)], - cmp: C, -) where - T: ToSql + Sync, - F: FromSqlOwned, - S: fmt::Display, - C: Fn(&T, &F) -> bool, -{ - for (val, repr) in checks.iter() { - let stmt = conn - .prepare(&format!("SELECT {}::{}", *repr, sql_type)) - .unwrap(); - let result: F = conn.query_one(&stmt, &[]).unwrap().get(0); - assert!(cmp(val, &result)); - - let stmt = conn.prepare(&format!("SELECT $1::{}", sql_type)).unwrap(); - let result: F = conn.query_one(&stmt, &[val]).unwrap().get(0); - assert!(cmp(val, &result)); - } -} - -#[test] -fn compile_fail() { - trybuild::TestCases::new().compile_fail("src/compile-fail/*.rs"); -} diff --git a/postgres-derive-test/src/transparent.rs b/postgres-derive-test/src/transparent.rs deleted file mode 100644 index 1614553d2..000000000 --- a/postgres-derive-test/src/transparent.rs +++ /dev/null @@ -1,18 +0,0 @@ -use postgres::{Client, NoTls}; -use postgres_types::{FromSql, ToSql}; - -#[test] -fn round_trip() { - #[derive(FromSql, ToSql, Debug, PartialEq)] - #[postgres(transparent)] - struct UserId(i32); - - assert_eq!( - Client::connect("user=postgres host=localhost port=5433", NoTls) - .unwrap() - .query_one("SELECT $1::integer", &[&UserId(123)]) - .unwrap() - .get::<_, UserId>(0), - UserId(123) - ); -} diff --git a/postgres-derive/CHANGELOG.md b/postgres-derive/CHANGELOG.md deleted file mode 100644 index dde466a97..000000000 --- a/postgres-derive/CHANGELOG.md +++ /dev/null @@ -1,27 +0,0 @@ -# Change Log - -## v0.4.3 - 2022-09-07 - -### Added - -* Added support for parameterized structs. - -## v0.4.2 - 2022-04-30 - -### Added - -* Added support for transparent wrapper types. - -## v0.4.1 - 2021-11-23 - -### Fixed - -* Fixed handling of struct fields using raw identifiers. - -## v0.4.0 - 2019-12-23 - -No changes - -## v0.4.0-alpha.1 - 2019-10-14 - -* Initial release diff --git a/postgres-derive/Cargo.toml b/postgres-derive/Cargo.toml deleted file mode 100644 index 22b50b707..000000000 --- a/postgres-derive/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "postgres-derive" -version = "0.4.3" -authors = ["Steven Fackler "] -license = "MIT/Apache-2.0" -edition = "2018" -description = "An internal crate used by postgres-types" -repository = "https://github.com/sfackler/rust-postgres" - -[lib] -proc-macro = true -test = false - -[dependencies] -syn = "1.0" -proc-macro2 = "1.0" -quote = "1.0" diff --git a/postgres-derive/LICENSE-APACHE b/postgres-derive/LICENSE-APACHE deleted file mode 120000 index 965b606f3..000000000 --- a/postgres-derive/LICENSE-APACHE +++ /dev/null @@ -1 +0,0 @@ -../LICENSE-APACHE \ No newline at end of file diff --git a/postgres-derive/LICENSE-MIT b/postgres-derive/LICENSE-MIT deleted file mode 120000 index 76219eb72..000000000 --- a/postgres-derive/LICENSE-MIT +++ /dev/null @@ -1 +0,0 @@ -../LICENSE-MIT \ No newline at end of file diff --git a/postgres-derive/src/accepts.rs b/postgres-derive/src/accepts.rs deleted file mode 100644 index 63473863a..000000000 --- a/postgres-derive/src/accepts.rs +++ /dev/null @@ -1,95 +0,0 @@ -use proc_macro2::{Span, TokenStream}; -use quote::quote; -use std::iter; -use syn::Ident; - -use crate::composites::Field; -use crate::enums::Variant; - -pub fn transparent_body(field: &syn::Field) -> TokenStream { - let ty = &field.ty; - - quote! { - <#ty as ::postgres_types::ToSql>::accepts(type_) - } -} - -pub fn domain_body(name: &str, field: &syn::Field) -> TokenStream { - let ty = &field.ty; - - quote! { - if type_.name() != #name { - return false; - } - - match *type_.kind() { - ::postgres_types::Kind::Domain(ref type_) => { - <#ty as ::postgres_types::ToSql>::accepts(type_) - } - _ => false, - } - } -} - -pub fn enum_body(name: &str, variants: &[Variant]) -> TokenStream { - let num_variants = variants.len(); - let variant_names = variants.iter().map(|v| &v.name); - - quote! { - if type_.name() != #name { - return false; - } - - match *type_.kind() { - ::postgres_types::Kind::Enum(ref variants) => { - if variants.len() != #num_variants { - return false; - } - - variants.iter().all(|v| { - match &**v { - #( - #variant_names => true, - )* - _ => false, - } - }) - } - _ => false, - } - } -} - -pub fn composite_body(name: &str, trait_: &str, fields: &[Field]) -> TokenStream { - let num_fields = fields.len(); - let trait_ = Ident::new(trait_, Span::call_site()); - let traits = iter::repeat(&trait_); - let field_names = fields.iter().map(|f| &f.name); - let field_types = fields.iter().map(|f| &f.type_); - - quote! { - if type_.name() != #name { - return false; - } - - match *type_.kind() { - ::postgres_types::Kind::Composite(ref fields) => { - if fields.len() != #num_fields { - return false; - } - - fields.iter().all(|f| { - match f.name() { - #( - #field_names => { - <#field_types as ::postgres_types::#traits>::accepts(f.type_()) - } - )* - _ => false, - } - }) - } - _ => false, - } - } -} diff --git a/postgres-derive/src/composites.rs b/postgres-derive/src/composites.rs deleted file mode 100644 index 15bfabc13..000000000 --- a/postgres-derive/src/composites.rs +++ /dev/null @@ -1,52 +0,0 @@ -use proc_macro2::Span; -use syn::{ - punctuated::Punctuated, Error, GenericParam, Generics, Ident, Path, PathSegment, Type, - TypeParamBound, -}; - -use crate::overrides::Overrides; - -pub struct Field { - pub name: String, - pub ident: Ident, - pub type_: Type, -} - -impl Field { - pub fn parse(raw: &syn::Field) -> Result { - let overrides = Overrides::extract(&raw.attrs)?; - - let ident = raw.ident.as_ref().unwrap().clone(); - Ok(Field { - name: overrides.name.unwrap_or_else(|| { - let name = ident.to_string(); - match name.strip_prefix("r#") { - Some(name) => name.to_string(), - None => name, - } - }), - ident, - type_: raw.ty.clone(), - }) - } -} - -pub(crate) fn append_generic_bound(mut generics: Generics, bound: &TypeParamBound) -> Generics { - for param in &mut generics.params { - if let GenericParam::Type(param) = param { - param.bounds.push(bound.to_owned()) - } - } - generics -} - -pub(crate) fn new_derive_path(last: PathSegment) -> Path { - let mut path = Path { - leading_colon: None, - segments: Punctuated::new(), - }; - path.segments - .push(Ident::new("postgres_types", Span::call_site()).into()); - path.segments.push(last); - path -} diff --git a/postgres-derive/src/enums.rs b/postgres-derive/src/enums.rs deleted file mode 100644 index 3c6bc7113..000000000 --- a/postgres-derive/src/enums.rs +++ /dev/null @@ -1,28 +0,0 @@ -use syn::{Error, Fields, Ident}; - -use crate::overrides::Overrides; - -pub struct Variant { - pub ident: Ident, - pub name: String, -} - -impl Variant { - pub fn parse(raw: &syn::Variant) -> Result { - match raw.fields { - Fields::Unit => {} - _ => { - return Err(Error::new_spanned( - raw, - "non-C-like enums are not supported", - )) - } - } - - let overrides = Overrides::extract(&raw.attrs)?; - Ok(Variant { - ident: raw.ident.clone(), - name: overrides.name.unwrap_or_else(|| raw.ident.to_string()), - }) - } -} diff --git a/postgres-derive/src/fromsql.rs b/postgres-derive/src/fromsql.rs deleted file mode 100644 index f458c6e3d..000000000 --- a/postgres-derive/src/fromsql.rs +++ /dev/null @@ -1,243 +0,0 @@ -use proc_macro2::{Span, TokenStream}; -use quote::{format_ident, quote}; -use std::iter; -use syn::{ - punctuated::Punctuated, token, AngleBracketedGenericArguments, Data, DataStruct, DeriveInput, - Error, Fields, GenericArgument, GenericParam, Generics, Ident, Lifetime, LifetimeDef, - PathArguments, PathSegment, -}; -use syn::{TraitBound, TraitBoundModifier, TypeParamBound}; - -use crate::accepts; -use crate::composites::Field; -use crate::composites::{append_generic_bound, new_derive_path}; -use crate::enums::Variant; -use crate::overrides::Overrides; - -pub fn expand_derive_fromsql(input: DeriveInput) -> Result { - let overrides = Overrides::extract(&input.attrs)?; - - if overrides.name.is_some() && overrides.transparent { - return Err(Error::new_spanned( - &input, - "#[postgres(transparent)] is not allowed with #[postgres(name = \"...\")]", - )); - } - - let name = overrides.name.unwrap_or_else(|| input.ident.to_string()); - - let (accepts_body, to_sql_body) = if overrides.transparent { - match input.data { - Data::Struct(DataStruct { - fields: Fields::Unnamed(ref fields), - .. - }) if fields.unnamed.len() == 1 => { - let field = fields.unnamed.first().unwrap(); - ( - accepts::transparent_body(field), - transparent_body(&input.ident, field), - ) - } - _ => { - return Err(Error::new_spanned( - input, - "#[postgres(transparent)] may only be applied to single field tuple structs", - )) - } - } - } else { - match input.data { - Data::Enum(ref data) => { - let variants = data - .variants - .iter() - .map(Variant::parse) - .collect::, _>>()?; - ( - accepts::enum_body(&name, &variants), - enum_body(&input.ident, &variants), - ) - } - Data::Struct(DataStruct { - fields: Fields::Unnamed(ref fields), - .. - }) if fields.unnamed.len() == 1 => { - let field = fields.unnamed.first().unwrap(); - ( - domain_accepts_body(&name, field), - domain_body(&input.ident, field), - ) - } - Data::Struct(DataStruct { - fields: Fields::Named(ref fields), - .. - }) => { - let fields = fields - .named - .iter() - .map(Field::parse) - .collect::, _>>()?; - ( - accepts::composite_body(&name, "FromSql", &fields), - composite_body(&input.ident, &fields), - ) - } - _ => { - return Err(Error::new_spanned( - input, - "#[derive(FromSql)] may only be applied to structs, single field tuple structs, and enums", - )) - } - } - }; - - let ident = &input.ident; - let (generics, lifetime) = build_generics(&input.generics); - let (impl_generics, _, _) = generics.split_for_impl(); - let (_, ty_generics, where_clause) = input.generics.split_for_impl(); - let out = quote! { - impl#impl_generics postgres_types::FromSql<#lifetime> for #ident#ty_generics #where_clause { - fn from_sql(_type: &postgres_types::Type, buf: &#lifetime [u8]) - -> std::result::Result<#ident#ty_generics, - std::boxed::Box> { - #to_sql_body - } - - fn accepts(type_: &postgres_types::Type) -> bool { - #accepts_body - } - } - }; - - Ok(out) -} - -fn transparent_body(ident: &Ident, field: &syn::Field) -> TokenStream { - let ty = &field.ty; - quote! { - <#ty as postgres_types::FromSql>::from_sql(_type, buf).map(#ident) - } -} - -fn enum_body(ident: &Ident, variants: &[Variant]) -> TokenStream { - let variant_names = variants.iter().map(|v| &v.name); - let idents = iter::repeat(ident); - let variant_idents = variants.iter().map(|v| &v.ident); - - quote! { - match std::str::from_utf8(buf)? { - #( - #variant_names => std::result::Result::Ok(#idents::#variant_idents), - )* - s => { - std::result::Result::Err( - std::convert::Into::into(format!("invalid variant `{}`", s))) - } - } - } -} - -// Domains are sometimes but not always just represented by the bare type (!?) -fn domain_accepts_body(name: &str, field: &syn::Field) -> TokenStream { - let ty = &field.ty; - let normal_body = accepts::domain_body(name, field); - - quote! { - if <#ty as postgres_types::FromSql>::accepts(type_) { - return true; - } - - #normal_body - } -} - -fn domain_body(ident: &Ident, field: &syn::Field) -> TokenStream { - let ty = &field.ty; - quote! { - <#ty as postgres_types::FromSql>::from_sql(_type, buf).map(#ident) - } -} - -fn composite_body(ident: &Ident, fields: &[Field]) -> TokenStream { - let temp_vars = &fields - .iter() - .map(|f| format_ident!("__{}", f.ident)) - .collect::>(); - let field_names = &fields.iter().map(|f| &f.name).collect::>(); - let field_idents = &fields.iter().map(|f| &f.ident).collect::>(); - - quote! { - let fields = match *_type.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - - let mut buf = buf; - let num_fields = postgres_types::private::read_be_i32(&mut buf)?; - if num_fields as usize != fields.len() { - return std::result::Result::Err( - std::convert::Into::into(format!("invalid field count: {} vs {}", num_fields, fields.len()))); - } - - #( - let mut #temp_vars = std::option::Option::None; - )* - - for field in fields { - let oid = postgres_types::private::read_be_i32(&mut buf)? as u32; - if oid != field.type_().oid() { - return std::result::Result::Err(std::convert::Into::into("unexpected OID")); - } - - match field.name() { - #( - #field_names => { - #temp_vars = std::option::Option::Some( - postgres_types::private::read_value(field.type_(), &mut buf)?); - } - )* - _ => unreachable!(), - } - } - - std::result::Result::Ok(#ident { - #( - #field_idents: #temp_vars.unwrap(), - )* - }) - } -} - -fn build_generics(source: &Generics) -> (Generics, Lifetime) { - // don't worry about lifetime name collisions, it doesn't make sense to derive FromSql on a struct with a lifetime - let lifetime = Lifetime::new("'a", Span::call_site()); - - let mut out = append_generic_bound(source.to_owned(), &new_fromsql_bound(&lifetime)); - out.params.insert( - 0, - GenericParam::Lifetime(LifetimeDef::new(lifetime.to_owned())), - ); - - (out, lifetime) -} - -fn new_fromsql_bound(lifetime: &Lifetime) -> TypeParamBound { - let mut path_segment: PathSegment = Ident::new("FromSql", Span::call_site()).into(); - let mut seg_args = Punctuated::new(); - seg_args.push(GenericArgument::Lifetime(lifetime.to_owned())); - path_segment.arguments = PathArguments::AngleBracketed(AngleBracketedGenericArguments { - colon2_token: None, - lt_token: token::Lt::default(), - args: seg_args, - gt_token: token::Gt::default(), - }); - - TypeParamBound::Trait(TraitBound { - lifetimes: None, - modifier: TraitBoundModifier::None, - paren_token: None, - path: new_derive_path(path_segment), - }) -} diff --git a/postgres-derive/src/lib.rs b/postgres-derive/src/lib.rs deleted file mode 100644 index 98e6add24..000000000 --- a/postgres-derive/src/lib.rs +++ /dev/null @@ -1,32 +0,0 @@ -//! An internal crate for `postgres-types`. - -#![recursion_limit = "256"] -extern crate proc_macro; - -use proc_macro::TokenStream; -use syn::parse_macro_input; - -mod accepts; -mod composites; -mod enums; -mod fromsql; -mod overrides; -mod tosql; - -#[proc_macro_derive(ToSql, attributes(postgres))] -pub fn derive_tosql(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input); - - tosql::expand_derive_tosql(input) - .unwrap_or_else(|e| e.to_compile_error()) - .into() -} - -#[proc_macro_derive(FromSql, attributes(postgres))] -pub fn derive_fromsql(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input); - - fromsql::expand_derive_fromsql(input) - .unwrap_or_else(|e| e.to_compile_error()) - .into() -} diff --git a/postgres-derive/src/overrides.rs b/postgres-derive/src/overrides.rs deleted file mode 100644 index c00d5a94b..000000000 --- a/postgres-derive/src/overrides.rs +++ /dev/null @@ -1,57 +0,0 @@ -use syn::{Attribute, Error, Lit, Meta, NestedMeta}; - -pub struct Overrides { - pub name: Option, - pub transparent: bool, -} - -impl Overrides { - pub fn extract(attrs: &[Attribute]) -> Result { - let mut overrides = Overrides { - name: None, - transparent: false, - }; - - for attr in attrs { - let attr = attr.parse_meta()?; - - if !attr.path().is_ident("postgres") { - continue; - } - - let list = match attr { - Meta::List(ref list) => list, - bad => return Err(Error::new_spanned(bad, "expected a #[postgres(...)]")), - }; - - for item in &list.nested { - match item { - NestedMeta::Meta(Meta::NameValue(meta)) => { - if !meta.path.is_ident("name") { - return Err(Error::new_spanned(&meta.path, "unknown override")); - } - - let value = match &meta.lit { - Lit::Str(s) => s.value(), - bad => { - return Err(Error::new_spanned(bad, "expected a string literal")) - } - }; - - overrides.name = Some(value); - } - NestedMeta::Meta(Meta::Path(ref path)) => { - if !path.is_ident("transparent") { - return Err(Error::new_spanned(path, "unknown override")); - } - - overrides.transparent = true; - } - bad => return Err(Error::new_spanned(bad, "unknown attribute")), - } - } - } - - Ok(overrides) - } -} diff --git a/postgres-derive/src/tosql.rs b/postgres-derive/src/tosql.rs deleted file mode 100644 index e51acc7fd..000000000 --- a/postgres-derive/src/tosql.rs +++ /dev/null @@ -1,198 +0,0 @@ -use proc_macro2::{Span, TokenStream}; -use quote::quote; -use std::iter; -use syn::{ - Data, DataStruct, DeriveInput, Error, Fields, Ident, TraitBound, TraitBoundModifier, - TypeParamBound, -}; - -use crate::accepts; -use crate::composites::Field; -use crate::composites::{append_generic_bound, new_derive_path}; -use crate::enums::Variant; -use crate::overrides::Overrides; - -pub fn expand_derive_tosql(input: DeriveInput) -> Result { - let overrides = Overrides::extract(&input.attrs)?; - - if overrides.name.is_some() && overrides.transparent { - return Err(Error::new_spanned( - &input, - "#[postgres(transparent)] is not allowed with #[postgres(name = \"...\")]", - )); - } - - let name = overrides.name.unwrap_or_else(|| input.ident.to_string()); - - let (accepts_body, to_sql_body) = if overrides.transparent { - match input.data { - Data::Struct(DataStruct { - fields: Fields::Unnamed(ref fields), - .. - }) if fields.unnamed.len() == 1 => { - let field = fields.unnamed.first().unwrap(); - - (accepts::transparent_body(field), transparent_body()) - } - _ => { - return Err(Error::new_spanned( - input, - "#[postgres(transparent)] may only be applied to single field tuple structs", - )); - } - } - } else { - match input.data { - Data::Enum(ref data) => { - let variants = data - .variants - .iter() - .map(Variant::parse) - .collect::, _>>()?; - ( - accepts::enum_body(&name, &variants), - enum_body(&input.ident, &variants), - ) - } - Data::Struct(DataStruct { - fields: Fields::Unnamed(ref fields), - .. - }) if fields.unnamed.len() == 1 => { - let field = fields.unnamed.first().unwrap(); - - (accepts::domain_body(&name, field), domain_body()) - } - Data::Struct(DataStruct { - fields: Fields::Named(ref fields), - .. - }) => { - let fields = fields - .named - .iter() - .map(Field::parse) - .collect::, _>>()?; - ( - accepts::composite_body(&name, "ToSql", &fields), - composite_body(&fields), - ) - } - _ => { - return Err(Error::new_spanned( - input, - "#[derive(ToSql)] may only be applied to structs, single field tuple structs, and enums", - )); - } - } - }; - - let ident = &input.ident; - let generics = append_generic_bound(input.generics.to_owned(), &new_tosql_bound()); - let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); - let out = quote! { - impl#impl_generics postgres_types::ToSql for #ident#ty_generics #where_clause { - fn to_sql(&self, - _type: &postgres_types::Type, - buf: &mut postgres_types::private::BytesMut) - -> std::result::Result> { - #to_sql_body - } - - fn accepts(type_: &postgres_types::Type) -> bool { - #accepts_body - } - - postgres_types::to_sql_checked!(); - } - }; - - Ok(out) -} - -fn transparent_body() -> TokenStream { - quote! { - postgres_types::ToSql::to_sql(&self.0, _type, buf) - } -} - -fn enum_body(ident: &Ident, variants: &[Variant]) -> TokenStream { - let idents = iter::repeat(ident); - let variant_idents = variants.iter().map(|v| &v.ident); - let variant_names = variants.iter().map(|v| &v.name); - - quote! { - let s = match *self { - #( - #idents::#variant_idents => #variant_names, - )* - }; - - buf.extend_from_slice(s.as_bytes()); - std::result::Result::Ok(postgres_types::IsNull::No) - } -} - -fn domain_body() -> TokenStream { - quote! { - let type_ = match *_type.kind() { - postgres_types::Kind::Domain(ref type_) => type_, - _ => unreachable!(), - }; - - postgres_types::ToSql::to_sql(&self.0, type_, buf) - } -} - -fn composite_body(fields: &[Field]) -> TokenStream { - let field_names = fields.iter().map(|f| &f.name); - let field_idents = fields.iter().map(|f| &f.ident); - - quote! { - let fields = match *_type.kind() { - postgres_types::Kind::Composite(ref fields) => fields, - _ => unreachable!(), - }; - - buf.extend_from_slice(&(fields.len() as i32).to_be_bytes()); - - for field in fields { - buf.extend_from_slice(&field.type_().oid().to_be_bytes()); - - let base = buf.len(); - buf.extend_from_slice(&[0; 4]); - let r = match field.name() { - #( - #field_names => postgres_types::ToSql::to_sql(&self.#field_idents, field.type_(), buf), - )* - _ => unreachable!(), - }; - - let count = match r? { - postgres_types::IsNull::Yes => -1, - postgres_types::IsNull::No => { - let len = buf.len() - base - 4; - if len > i32::max_value() as usize { - return std::result::Result::Err( - std::convert::Into::into("value too large to transmit")); - } - len as i32 - } - }; - - buf[base..base + 4].copy_from_slice(&count.to_be_bytes()); - } - - std::result::Result::Ok(postgres_types::IsNull::No) - } -} - -fn new_tosql_bound() -> TypeParamBound { - TypeParamBound::Trait(TraitBound { - lifetimes: None, - modifier: TraitBoundModifier::None, - paren_token: None, - path: new_derive_path(Ident::new("ToSql", Span::call_site()).into()), - }) -} diff --git a/postgres-native-tls/CHANGELOG.md b/postgres-native-tls/CHANGELOG.md deleted file mode 100644 index 9eb7ab800..000000000 --- a/postgres-native-tls/CHANGELOG.md +++ /dev/null @@ -1,37 +0,0 @@ -# Change Log - -## v0.5.0 - 2020-12-25 - -### Changed - -* Upgraded to `tokio-postgres` 0.7. - -## v0.4.0 - 2020-10-17 - -### Changed - -* Upgraded to `tokio-postgres` 0.6. - -## v0.3.0 - 2019-12-23 - -### Changed - -* Upgraded to `tokio-postgres` 0.5. - -## v0.3.0-alpha.2 - 2019-11-27 - -### Changed - -* Upgraded to `tokio-postgres` v0.5.0-alpha.2. - -## v0.3.0-alpha.1 - 2019-10-14 - -### Changed - -* Updated to `tokio-postgres` v0.5.0-alpha.1. - -## v0.2.0-rc.1 - 2019-06-29 - -### Changed - -* Updated to `tokio-postgres` v0.4.0-rc. diff --git a/postgres-native-tls/Cargo.toml b/postgres-native-tls/Cargo.toml deleted file mode 100644 index 1f2f6385d..000000000 --- a/postgres-native-tls/Cargo.toml +++ /dev/null @@ -1,27 +0,0 @@ -[package] -name = "postgres-native-tls" -version = "0.5.0" -authors = ["Steven Fackler "] -edition = "2018" -license = "MIT/Apache-2.0" -description = "TLS support for tokio-postgres via native-tls" -repository = "https://github.com/sfackler/rust-postgres" -readme = "../README.md" - -[badges] -circle-ci = { repository = "sfackler/rust-postgres" } - -[features] -default = ["runtime"] -runtime = ["tokio-postgres/runtime"] - -[dependencies] -native-tls = "0.2" -tokio = "1.0" -tokio-native-tls = "0.3" -tokio-postgres = { version = "0.7.0", path = "../tokio-postgres", default-features = false } - -[dev-dependencies] -futures-util = "0.3" -tokio = { version = "1.0", features = ["macros", "net", "rt"] } -postgres = { version = "0.19.0", path = "../postgres" } diff --git a/postgres-native-tls/LICENSE-APACHE b/postgres-native-tls/LICENSE-APACHE deleted file mode 120000 index 965b606f3..000000000 --- a/postgres-native-tls/LICENSE-APACHE +++ /dev/null @@ -1 +0,0 @@ -../LICENSE-APACHE \ No newline at end of file diff --git a/postgres-native-tls/LICENSE-MIT b/postgres-native-tls/LICENSE-MIT deleted file mode 120000 index 76219eb72..000000000 --- a/postgres-native-tls/LICENSE-MIT +++ /dev/null @@ -1 +0,0 @@ -../LICENSE-MIT \ No newline at end of file diff --git a/postgres-native-tls/src/lib.rs b/postgres-native-tls/src/lib.rs deleted file mode 100644 index a06f185b5..000000000 --- a/postgres-native-tls/src/lib.rs +++ /dev/null @@ -1,182 +0,0 @@ -//! TLS support for `tokio-postgres` and `postgres` via `native-tls`. -//! -//! # Examples -//! -//! ```no_run -//! use native_tls::{Certificate, TlsConnector}; -//! # #[cfg(feature = "runtime")] -//! use postgres_native_tls::MakeTlsConnector; -//! use std::fs; -//! -//! # fn main() -> Result<(), Box> { -//! # #[cfg(feature = "runtime")] { -//! let cert = fs::read("database_cert.pem")?; -//! let cert = Certificate::from_pem(&cert)?; -//! let connector = TlsConnector::builder() -//! .add_root_certificate(cert) -//! .build()?; -//! let connector = MakeTlsConnector::new(connector); -//! -//! let connect_future = tokio_postgres::connect( -//! "host=localhost user=postgres sslmode=require", -//! connector, -//! ); -//! # } -//! -//! // ... -//! # Ok(()) -//! # } -//! ``` -//! -//! ```no_run -//! use native_tls::{Certificate, TlsConnector}; -//! # #[cfg(feature = "runtime")] -//! use postgres_native_tls::MakeTlsConnector; -//! use std::fs; -//! -//! # fn main() -> Result<(), Box> { -//! # #[cfg(feature = "runtime")] { -//! let cert = fs::read("database_cert.pem")?; -//! let cert = Certificate::from_pem(&cert)?; -//! let connector = TlsConnector::builder() -//! .add_root_certificate(cert) -//! .build()?; -//! let connector = MakeTlsConnector::new(connector); -//! -//! let client = postgres::Client::connect( -//! "host=localhost user=postgres sslmode=require", -//! connector, -//! )?; -//! # } -//! # Ok(()) -//! # } -//! ``` -#![warn(rust_2018_idioms, clippy::all, missing_docs)] - -use std::future::Future; -use std::io; -use std::pin::Pin; -use std::task::{Context, Poll}; -use tokio::io::{AsyncRead, AsyncWrite, BufReader, ReadBuf}; -use tokio_postgres::tls; -#[cfg(feature = "runtime")] -use tokio_postgres::tls::MakeTlsConnect; -use tokio_postgres::tls::{ChannelBinding, TlsConnect}; - -#[cfg(test)] -mod test; - -/// A `MakeTlsConnect` implementation using the `native-tls` crate. -/// -/// Requires the `runtime` Cargo feature (enabled by default). -#[cfg(feature = "runtime")] -#[derive(Clone)] -pub struct MakeTlsConnector(native_tls::TlsConnector); - -#[cfg(feature = "runtime")] -impl MakeTlsConnector { - /// Creates a new connector. - pub fn new(connector: native_tls::TlsConnector) -> MakeTlsConnector { - MakeTlsConnector(connector) - } -} - -#[cfg(feature = "runtime")] -impl MakeTlsConnect for MakeTlsConnector -where - S: AsyncRead + AsyncWrite + Unpin + 'static + Send, -{ - type Stream = TlsStream; - type TlsConnect = TlsConnector; - type Error = native_tls::Error; - - fn make_tls_connect(&mut self, domain: &str) -> Result { - Ok(TlsConnector::new(self.0.clone(), domain)) - } -} - -/// A `TlsConnect` implementation using the `native-tls` crate. -pub struct TlsConnector { - connector: tokio_native_tls::TlsConnector, - domain: String, -} - -impl TlsConnector { - /// Creates a new connector configured to connect to the specified domain. - pub fn new(connector: native_tls::TlsConnector, domain: &str) -> TlsConnector { - TlsConnector { - connector: tokio_native_tls::TlsConnector::from(connector), - domain: domain.to_string(), - } - } -} - -impl TlsConnect for TlsConnector -where - S: AsyncRead + AsyncWrite + Unpin + 'static + Send, -{ - type Stream = TlsStream; - type Error = native_tls::Error; - #[allow(clippy::type_complexity)] - type Future = Pin, native_tls::Error>> + Send>>; - - fn connect(self, stream: S) -> Self::Future { - let stream = BufReader::with_capacity(8192, stream); - let future = async move { - let stream = self.connector.connect(&self.domain, stream).await?; - - Ok(TlsStream(stream)) - }; - - Box::pin(future) - } -} - -/// The stream returned by `TlsConnector`. -pub struct TlsStream(tokio_native_tls::TlsStream>); - -impl AsyncRead for TlsStream -where - S: AsyncRead + AsyncWrite + Unpin, -{ - fn poll_read( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &mut ReadBuf<'_>, - ) -> Poll> { - Pin::new(&mut self.0).poll_read(cx, buf) - } -} - -impl AsyncWrite for TlsStream -where - S: AsyncRead + AsyncWrite + Unpin, -{ - fn poll_write( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &[u8], - ) -> Poll> { - Pin::new(&mut self.0).poll_write(cx, buf) - } - - fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - Pin::new(&mut self.0).poll_flush(cx) - } - - fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - Pin::new(&mut self.0).poll_shutdown(cx) - } -} - -impl tls::TlsStream for TlsStream -where - S: AsyncRead + AsyncWrite + Unpin, -{ - fn channel_binding(&self) -> ChannelBinding { - match self.0.get_ref().tls_server_end_point().ok().flatten() { - Some(buf) => ChannelBinding::tls_server_end_point(buf), - None => ChannelBinding::none(), - } - } -} diff --git a/postgres-native-tls/src/test.rs b/postgres-native-tls/src/test.rs deleted file mode 100644 index 25cc6fdbd..000000000 --- a/postgres-native-tls/src/test.rs +++ /dev/null @@ -1,100 +0,0 @@ -use futures_util::FutureExt; -use native_tls::{self, Certificate}; -use tokio::net::TcpStream; -use tokio_postgres::tls::TlsConnect; - -#[cfg(feature = "runtime")] -use crate::MakeTlsConnector; -use crate::TlsConnector; - -async fn smoke_test(s: &str, tls: T) -where - T: TlsConnect, - T::Stream: 'static + Send, -{ - let stream = TcpStream::connect("127.0.0.1:5433").await.unwrap(); - - let builder = s.parse::().unwrap(); - let (client, connection) = builder.connect_raw(stream, tls).await.unwrap(); - - let connection = connection.map(|r| r.unwrap()); - tokio::spawn(connection); - - let stmt = client.prepare("SELECT $1::INT4").await.unwrap(); - let rows = client.query(&stmt, &[&1i32]).await.unwrap(); - - assert_eq!(rows.len(), 1); - assert_eq!(rows[0].get::<_, i32>(0), 1); -} - -#[tokio::test] -async fn require() { - let connector = native_tls::TlsConnector::builder() - .add_root_certificate( - Certificate::from_pem(include_bytes!("../../test/server.crt")).unwrap(), - ) - .build() - .unwrap(); - smoke_test( - "user=ssl_user dbname=postgres sslmode=require", - TlsConnector::new(connector, "localhost"), - ) - .await; -} - -#[tokio::test] -async fn prefer() { - let connector = native_tls::TlsConnector::builder() - .add_root_certificate( - Certificate::from_pem(include_bytes!("../../test/server.crt")).unwrap(), - ) - .build() - .unwrap(); - smoke_test( - "user=ssl_user dbname=postgres", - TlsConnector::new(connector, "localhost"), - ) - .await; -} - -#[tokio::test] -async fn scram_user() { - let connector = native_tls::TlsConnector::builder() - .add_root_certificate( - Certificate::from_pem(include_bytes!("../../test/server.crt")).unwrap(), - ) - .build() - .unwrap(); - smoke_test( - "user=scram_user password=password dbname=postgres sslmode=require", - TlsConnector::new(connector, "localhost"), - ) - .await; -} - -#[tokio::test] -#[cfg(feature = "runtime")] -async fn runtime() { - let connector = native_tls::TlsConnector::builder() - .add_root_certificate( - Certificate::from_pem(include_bytes!("../../test/server.crt")).unwrap(), - ) - .build() - .unwrap(); - let connector = MakeTlsConnector::new(connector); - - let (client, connection) = tokio_postgres::connect( - "host=localhost port=5433 user=postgres sslmode=require", - connector, - ) - .await - .unwrap(); - let connection = connection.map(|r| r.unwrap()); - tokio::spawn(connection); - - let stmt = client.prepare("SELECT $1::INT4").await.unwrap(); - let rows = client.query(&stmt, &[&1i32]).await.unwrap(); - - assert_eq!(rows.len(), 1); - assert_eq!(rows[0].get::<_, i32>(0), 1); -} diff --git a/postgres-openssl/CHANGELOG.md b/postgres-openssl/CHANGELOG.md deleted file mode 100644 index 346214ae8..000000000 --- a/postgres-openssl/CHANGELOG.md +++ /dev/null @@ -1,37 +0,0 @@ -# Change Log - -## v0.5.0 - 2020-12-25 - -### Changed - -* Upgraded to `tokio-postgres` 0.7. - -## v0.4.0 - 2020-10-17 - -### Changed - -* Upgraded to `tokio-postgres` 0.6. - -## v0.3.0 - 2019-12-23 - -### Changed - -* Upgraded to `tokio-postgres` 0.5. - -## v0.3.0-alpha.2 - 2019-11-27 - -### Changed - -* Upgraded `tokio-postgres` v0.5.0-alpha.2. - -## v0.3.0-alpha.1 - 2019-10-14 - -### Changed - -* Updated to `tokio-postgres` v0.5.0-alpha.1. - -## v0.2.0-rc.1 - 2019-03-06 - -### Changed - -* Updated to `tokio-postgres` v0.4.0-rc. diff --git a/postgres-openssl/Cargo.toml b/postgres-openssl/Cargo.toml deleted file mode 100644 index 8671308af..000000000 --- a/postgres-openssl/Cargo.toml +++ /dev/null @@ -1,27 +0,0 @@ -[package] -name = "postgres-openssl" -version = "0.5.0" -authors = ["Steven Fackler "] -edition = "2018" -license = "MIT/Apache-2.0" -description = "TLS support for tokio-postgres via openssl" -repository = "https://github.com/sfackler/rust-postgres" -readme = "../README.md" - -[badges] -circle-ci = { repository = "sfackler/rust-postgres" } - -[features] -default = ["runtime"] -runtime = ["tokio-postgres/runtime"] - -[dependencies] -openssl = "0.10" -tokio = "1.0" -tokio-openssl = "0.6" -tokio-postgres = { version = "0.7.0", path = "../tokio-postgres", default-features = false } - -[dev-dependencies] -futures-util = "0.3" -tokio = { version = "1.0", features = ["macros", "net", "rt"] } -postgres = { version = "0.19.0", path = "../postgres" } diff --git a/postgres-openssl/LICENSE-APACHE b/postgres-openssl/LICENSE-APACHE deleted file mode 120000 index 965b606f3..000000000 --- a/postgres-openssl/LICENSE-APACHE +++ /dev/null @@ -1 +0,0 @@ -../LICENSE-APACHE \ No newline at end of file diff --git a/postgres-openssl/LICENSE-MIT b/postgres-openssl/LICENSE-MIT deleted file mode 120000 index 76219eb72..000000000 --- a/postgres-openssl/LICENSE-MIT +++ /dev/null @@ -1 +0,0 @@ -../LICENSE-MIT \ No newline at end of file diff --git a/postgres-openssl/src/lib.rs b/postgres-openssl/src/lib.rs deleted file mode 100644 index 837663fe7..000000000 --- a/postgres-openssl/src/lib.rs +++ /dev/null @@ -1,252 +0,0 @@ -//! TLS support for `tokio-postgres` and `postgres` via `openssl`. -//! -//! # Examples -//! -//! ```no_run -//! use openssl::ssl::{SslConnector, SslMethod}; -//! # #[cfg(feature = "runtime")] -//! use postgres_openssl::MakeTlsConnector; -//! -//! # fn main() -> Result<(), Box> { -//! # #[cfg(feature = "runtime")] { -//! let mut builder = SslConnector::builder(SslMethod::tls())?; -//! builder.set_ca_file("database_cert.pem")?; -//! let connector = MakeTlsConnector::new(builder.build()); -//! -//! let connect_future = tokio_postgres::connect( -//! "host=localhost user=postgres sslmode=require", -//! connector, -//! ); -//! # } -//! -//! // ... -//! # Ok(()) -//! # } -//! ``` -//! -//! ```no_run -//! use openssl::ssl::{SslConnector, SslMethod}; -//! # #[cfg(feature = "runtime")] -//! use postgres_openssl::MakeTlsConnector; -//! -//! # fn main() -> Result<(), Box> { -//! # #[cfg(feature = "runtime")] { -//! let mut builder = SslConnector::builder(SslMethod::tls())?; -//! builder.set_ca_file("database_cert.pem")?; -//! let connector = MakeTlsConnector::new(builder.build()); -//! -//! let client = postgres::Client::connect( -//! "host=localhost user=postgres sslmode=require", -//! connector, -//! )?; -//! # } -//! -//! // ... -//! # Ok(()) -//! # } -//! ``` -#![warn(rust_2018_idioms, clippy::all, missing_docs)] - -#[cfg(feature = "runtime")] -use openssl::error::ErrorStack; -use openssl::hash::MessageDigest; -use openssl::nid::Nid; -#[cfg(feature = "runtime")] -use openssl::ssl::SslConnector; -use openssl::ssl::{self, ConnectConfiguration, SslRef}; -use openssl::x509::X509VerifyResult; -use std::error::Error; -use std::fmt::{self, Debug}; -use std::future::Future; -use std::io; -use std::pin::Pin; -#[cfg(feature = "runtime")] -use std::sync::Arc; -use std::task::{Context, Poll}; -use tokio::io::{AsyncRead, AsyncWrite, BufReader, ReadBuf}; -use tokio_openssl::SslStream; -use tokio_postgres::tls; -#[cfg(feature = "runtime")] -use tokio_postgres::tls::MakeTlsConnect; -use tokio_postgres::tls::{ChannelBinding, TlsConnect}; - -#[cfg(test)] -mod test; - -type ConfigCallback = - dyn Fn(&mut ConnectConfiguration, &str) -> Result<(), ErrorStack> + Sync + Send; - -/// A `MakeTlsConnect` implementation using the `openssl` crate. -/// -/// Requires the `runtime` Cargo feature (enabled by default). -#[cfg(feature = "runtime")] -#[derive(Clone)] -pub struct MakeTlsConnector { - connector: SslConnector, - config: Arc, -} - -#[cfg(feature = "runtime")] -impl MakeTlsConnector { - /// Creates a new connector. - pub fn new(connector: SslConnector) -> MakeTlsConnector { - MakeTlsConnector { - connector, - config: Arc::new(|_, _| Ok(())), - } - } - - /// Sets a callback used to apply per-connection configuration. - /// - /// The the callback is provided the domain name along with the `ConnectConfiguration`. - pub fn set_callback(&mut self, f: F) - where - F: Fn(&mut ConnectConfiguration, &str) -> Result<(), ErrorStack> + 'static + Sync + Send, - { - self.config = Arc::new(f); - } -} - -#[cfg(feature = "runtime")] -impl MakeTlsConnect for MakeTlsConnector -where - S: AsyncRead + AsyncWrite + Unpin + Debug + 'static + Sync + Send, -{ - type Stream = TlsStream; - type TlsConnect = TlsConnector; - type Error = ErrorStack; - - fn make_tls_connect(&mut self, domain: &str) -> Result { - let mut ssl = self.connector.configure()?; - (self.config)(&mut ssl, domain)?; - Ok(TlsConnector::new(ssl, domain)) - } -} - -/// A `TlsConnect` implementation using the `openssl` crate. -pub struct TlsConnector { - ssl: ConnectConfiguration, - domain: String, -} - -impl TlsConnector { - /// Creates a new connector configured to connect to the specified domain. - pub fn new(ssl: ConnectConfiguration, domain: &str) -> TlsConnector { - TlsConnector { - ssl, - domain: domain.to_string(), - } - } -} - -impl TlsConnect for TlsConnector -where - S: AsyncRead + AsyncWrite + Unpin + Send + 'static, -{ - type Stream = TlsStream; - type Error = Box; - #[allow(clippy::type_complexity)] - type Future = Pin, Self::Error>> + Send>>; - - fn connect(self, stream: S) -> Self::Future { - let stream = BufReader::with_capacity(8192, stream); - let future = async move { - let ssl = self.ssl.into_ssl(&self.domain)?; - let mut stream = SslStream::new(ssl, stream)?; - match Pin::new(&mut stream).connect().await { - Ok(()) => Ok(TlsStream(stream)), - Err(error) => Err(Box::new(ConnectError { - error, - verify_result: stream.ssl().verify_result(), - }) as _), - } - }; - - Box::pin(future) - } -} - -#[derive(Debug)] -struct ConnectError { - error: ssl::Error, - verify_result: X509VerifyResult, -} - -impl fmt::Display for ConnectError { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&self.error, fmt)?; - - if self.verify_result != X509VerifyResult::OK { - fmt.write_str(": ")?; - fmt::Display::fmt(&self.verify_result, fmt)?; - } - - Ok(()) - } -} - -impl Error for ConnectError { - fn source(&self) -> Option<&(dyn Error + 'static)> { - Some(&self.error) - } -} - -/// The stream returned by `TlsConnector`. -pub struct TlsStream(SslStream>); - -impl AsyncRead for TlsStream -where - S: AsyncRead + AsyncWrite + Unpin, -{ - fn poll_read( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &mut ReadBuf<'_>, - ) -> Poll> { - Pin::new(&mut self.0).poll_read(cx, buf) - } -} - -impl AsyncWrite for TlsStream -where - S: AsyncRead + AsyncWrite + Unpin, -{ - fn poll_write( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &[u8], - ) -> Poll> { - Pin::new(&mut self.0).poll_write(cx, buf) - } - - fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - Pin::new(&mut self.0).poll_flush(cx) - } - - fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - Pin::new(&mut self.0).poll_shutdown(cx) - } -} - -impl tls::TlsStream for TlsStream -where - S: AsyncRead + AsyncWrite + Unpin, -{ - fn channel_binding(&self) -> ChannelBinding { - match tls_server_end_point(self.0.ssl()) { - Some(buf) => ChannelBinding::tls_server_end_point(buf), - None => ChannelBinding::none(), - } - } -} - -fn tls_server_end_point(ssl: &SslRef) -> Option> { - let cert = ssl.peer_certificate()?; - let algo_nid = cert.signature_algorithm().object().nid(); - let signature_algorithms = algo_nid.signature_algorithms()?; - let md = match signature_algorithms.digest { - Nid::MD5 | Nid::SHA1 => MessageDigest::sha256(), - nid => MessageDigest::from_nid(nid)?, - }; - cert.digest(md).ok().map(|b| b.to_vec()) -} diff --git a/postgres-openssl/src/test.rs b/postgres-openssl/src/test.rs deleted file mode 100644 index b361ee446..000000000 --- a/postgres-openssl/src/test.rs +++ /dev/null @@ -1,111 +0,0 @@ -use futures_util::FutureExt; -use openssl::ssl::{SslConnector, SslMethod}; -use tokio::net::TcpStream; -use tokio_postgres::tls::TlsConnect; - -use super::*; - -async fn smoke_test(s: &str, tls: T) -where - T: TlsConnect, - T::Stream: 'static + Send, -{ - let stream = TcpStream::connect("127.0.0.1:5433").await.unwrap(); - - let builder = s.parse::().unwrap(); - let (client, connection) = builder.connect_raw(stream, tls).await.unwrap(); - - let connection = connection.map(|r| r.unwrap()); - tokio::spawn(connection); - - let stmt = client.prepare("SELECT $1::INT4").await.unwrap(); - let rows = client.query(&stmt, &[&1i32]).await.unwrap(); - - assert_eq!(rows.len(), 1); - assert_eq!(rows[0].get::<_, i32>(0), 1); -} - -#[tokio::test] -async fn require() { - let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); - builder.set_ca_file("../test/server.crt").unwrap(); - let ctx = builder.build(); - smoke_test( - "user=ssl_user dbname=postgres sslmode=require", - TlsConnector::new(ctx.configure().unwrap(), "localhost"), - ) - .await; -} - -#[tokio::test] -async fn prefer() { - let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); - builder.set_ca_file("../test/server.crt").unwrap(); - let ctx = builder.build(); - smoke_test( - "user=ssl_user dbname=postgres", - TlsConnector::new(ctx.configure().unwrap(), "localhost"), - ) - .await; -} - -#[tokio::test] -async fn scram_user() { - let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); - builder.set_ca_file("../test/server.crt").unwrap(); - let ctx = builder.build(); - smoke_test( - "user=scram_user password=password dbname=postgres sslmode=require", - TlsConnector::new(ctx.configure().unwrap(), "localhost"), - ) - .await; -} - -#[tokio::test] -async fn require_channel_binding_err() { - let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); - builder.set_ca_file("../test/server.crt").unwrap(); - let ctx = builder.build(); - let connector = TlsConnector::new(ctx.configure().unwrap(), "localhost"); - - let stream = TcpStream::connect("127.0.0.1:5433").await.unwrap(); - let builder = "user=pass_user password=password dbname=postgres channel_binding=require" - .parse::() - .unwrap(); - builder.connect_raw(stream, connector).await.err().unwrap(); -} - -#[tokio::test] -async fn require_channel_binding_ok() { - let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); - builder.set_ca_file("../test/server.crt").unwrap(); - let ctx = builder.build(); - smoke_test( - "user=scram_user password=password dbname=postgres channel_binding=require", - TlsConnector::new(ctx.configure().unwrap(), "localhost"), - ) - .await; -} - -#[tokio::test] -#[cfg(feature = "runtime")] -async fn runtime() { - let mut builder = SslConnector::builder(SslMethod::tls()).unwrap(); - builder.set_ca_file("../test/server.crt").unwrap(); - let connector = MakeTlsConnector::new(builder.build()); - - let (client, connection) = tokio_postgres::connect( - "host=localhost port=5433 user=postgres sslmode=require", - connector, - ) - .await - .unwrap(); - let connection = connection.map(|r| r.unwrap()); - tokio::spawn(connection); - - let stmt = client.prepare("SELECT $1::INT4").await.unwrap(); - let rows = client.query(&stmt, &[&1i32]).await.unwrap(); - - assert_eq!(rows.len(), 1); - assert_eq!(rows[0].get::<_, i32>(0), 1); -} diff --git a/postgres-types/Cargo.toml b/postgres-types/Cargo.toml index 3f9245c73..1414f3cf0 100644 --- a/postgres-types/Cargo.toml +++ b/postgres-types/Cargo.toml @@ -11,7 +11,6 @@ keywords = ["database", "postgres", "postgresql", "sql"] categories = ["database"] [features] -derive = ["postgres-derive"] array-impls = ["array-init"] with-bit-vec-0_6 = ["bit-vec-06"] with-cidr-0_2 = ["cidr-02"] @@ -30,7 +29,6 @@ with-time-0_3 = ["time-03"] bytes = "1.0" fallible-iterator = "0.2" postgres-protocol = { version = "0.6.4", path = "../postgres-protocol" } -postgres-derive = { version = "0.4.2", optional = true, path = "../postgres-derive" } array-init = { version = "2", optional = true } bit-vec-06 = { version = "0.6", package = "bit-vec", optional = true } diff --git a/postgres-types/src/lib.rs b/postgres-types/src/lib.rs index 79dd92996..6ff4becb8 100644 --- a/postgres-types/src/lib.rs +++ b/postgres-types/src/lib.rs @@ -140,9 +140,6 @@ use std::net::IpAddr; use std::sync::Arc; use std::time::{Duration, SystemTime, UNIX_EPOCH}; -#[cfg(feature = "derive")] -pub use postgres_derive::{FromSql, ToSql}; - #[cfg(feature = "with-serde_json-1")] pub use crate::serde_json_1::Json; use crate::type_gen::{Inner, Other};