mirror of
https://github.com/launchbadge/sqlx
synced 2024-11-10 06:24:16 +00:00
Support MACADDR in Postgres (#1329)
This commit is contained in:
parent
0abbcc510f
commit
be189bd11e
10 changed files with 136 additions and 0 deletions
25
Cargo.lock
generated
25
Cargo.lock
generated
|
@ -1,5 +1,7 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "actix-rt"
|
||||
version = "2.2.0"
|
||||
|
@ -1270,6 +1272,16 @@ dependencies = [
|
|||
"value-bag",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mac_address"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d9bb26482176bddeea173ceaa2acec85146d20cdcc631eafaf9d605d3d4fc23"
|
||||
dependencies = [
|
||||
"nix",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "maplit"
|
||||
version = "1.0.2"
|
||||
|
@ -1375,6 +1387,18 @@ dependencies = [
|
|||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.19.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2ccba0cfe4fdf15982d1674c69b1fd80bad427d293849982668dfe454bd61f2"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cc",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "6.1.2"
|
||||
|
@ -2343,6 +2367,7 @@ dependencies = [
|
|||
"libc",
|
||||
"libsqlite3-sys",
|
||||
"log",
|
||||
"mac_address",
|
||||
"md-5",
|
||||
"memchr",
|
||||
"num-bigint 0.3.2",
|
||||
|
|
|
@ -59,6 +59,7 @@ all-types = [
|
|||
"time",
|
||||
"chrono",
|
||||
"ipnetwork",
|
||||
"mac_address",
|
||||
"uuid",
|
||||
"bit-vec",
|
||||
"bstr",
|
||||
|
@ -121,6 +122,7 @@ bigdecimal = ["sqlx-core/bigdecimal", "sqlx-macros/bigdecimal"]
|
|||
decimal = ["sqlx-core/decimal", "sqlx-macros/decimal"]
|
||||
chrono = ["sqlx-core/chrono", "sqlx-macros/chrono"]
|
||||
ipnetwork = ["sqlx-core/ipnetwork", "sqlx-macros/ipnetwork"]
|
||||
mac_address = ["sqlx-core/mac_address", "sqlx-macros/mac_address"]
|
||||
uuid = ["sqlx-core/uuid", "sqlx-macros/uuid"]
|
||||
json = ["sqlx-core/json", "sqlx-macros/json"]
|
||||
time = ["sqlx-core/time", "sqlx-macros/time"]
|
||||
|
|
|
@ -54,6 +54,7 @@ all-types = [
|
|||
"bigdecimal",
|
||||
"decimal",
|
||||
"ipnetwork",
|
||||
"mac_address",
|
||||
"json",
|
||||
"uuid",
|
||||
"bit-vec",
|
||||
|
@ -125,6 +126,7 @@ hex = "0.4.2"
|
|||
hmac = { version = "0.10.1", default-features = false, optional = true }
|
||||
itoa = "0.4.5"
|
||||
ipnetwork = { version = "0.17.0", default-features = false, optional = true }
|
||||
mac_address = { version = "1.1", default-features = false, optional = true }
|
||||
libc = "0.2.71"
|
||||
libsqlite3-sys = { version = "0.22.0", optional = true, default-features = false, features = [
|
||||
"pkg-config",
|
||||
|
|
|
@ -198,6 +198,8 @@ impl PgTypeInfo {
|
|||
.contains(self)
|
||||
{
|
||||
Some("ipnetwork")
|
||||
} else if [PgTypeInfo::MACADDR].contains(self) {
|
||||
Some("mac_address")
|
||||
} else if [PgTypeInfo::NUMERIC, PgTypeInfo::NUMERIC_ARRAY].contains(self) {
|
||||
Some("bigdecimal")
|
||||
} else {
|
||||
|
|
63
sqlx-core/src/postgres/types/mac_address.rs
Normal file
63
sqlx-core/src/postgres/types/mac_address.rs
Normal file
|
@ -0,0 +1,63 @@
|
|||
use mac_address::MacAddress;
|
||||
|
||||
use std::convert::TryInto;
|
||||
|
||||
use crate::decode::Decode;
|
||||
use crate::encode::{Encode, IsNull};
|
||||
use crate::error::BoxDynError;
|
||||
use crate::postgres::{PgArgumentBuffer, PgTypeInfo, PgValueFormat, PgValueRef, Postgres};
|
||||
use crate::types::Type;
|
||||
|
||||
impl Type<Postgres> for MacAddress {
|
||||
fn type_info() -> PgTypeInfo {
|
||||
PgTypeInfo::MACADDR
|
||||
}
|
||||
|
||||
fn compatible(ty: &PgTypeInfo) -> bool {
|
||||
*ty == PgTypeInfo::MACADDR
|
||||
}
|
||||
}
|
||||
|
||||
impl Type<Postgres> for [MacAddress] {
|
||||
fn type_info() -> PgTypeInfo {
|
||||
PgTypeInfo::MACADDR_ARRAY
|
||||
}
|
||||
}
|
||||
|
||||
impl Type<Postgres> for Vec<MacAddress> {
|
||||
fn type_info() -> PgTypeInfo {
|
||||
<[MacAddress] as Type<Postgres>>::type_info()
|
||||
}
|
||||
|
||||
fn compatible(ty: &PgTypeInfo) -> bool {
|
||||
<[MacAddress] as Type<Postgres>>::compatible(ty)
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode<'_, Postgres> for MacAddress {
|
||||
fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull {
|
||||
buf.extend_from_slice(&self.bytes()); // write just the address
|
||||
IsNull::No
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> usize {
|
||||
6
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode<'_, Postgres> for MacAddress {
|
||||
fn decode(value: PgValueRef<'_>) -> Result<Self, BoxDynError> {
|
||||
let bytes = match value.format() {
|
||||
PgValueFormat::Binary => value.as_bytes()?,
|
||||
PgValueFormat::Text => {
|
||||
return Ok(value.as_str()?.parse()?);
|
||||
}
|
||||
};
|
||||
|
||||
if bytes.len() == 6 {
|
||||
return Ok(MacAddress::new(bytes.try_into().unwrap()));
|
||||
}
|
||||
|
||||
Err("invalid data received when expecting an MACADDR".into())
|
||||
}
|
||||
}
|
|
@ -73,6 +73,14 @@
|
|||
//! |---------------------------------------|------------------------------------------------------|
|
||||
//! | `ipnetwork::IpNetwork` | INET, CIDR |
|
||||
//!
|
||||
//! ### [`mac_address`](https://crates.io/crates/mac_address)
|
||||
//!
|
||||
//! Requires the `mac_address` Cargo feature flag.
|
||||
//!
|
||||
//! | Rust type | Postgres type(s) |
|
||||
//! |---------------------------------------|------------------------------------------------------|
|
||||
//! | `mac_address::MacAddress` | MACADDR |
|
||||
//!
|
||||
//! ### [`bit-vec`](https://crates.io/crates/bit-vec)
|
||||
//!
|
||||
//! Requires the `bit-vec` Cargo feature flag.
|
||||
|
@ -194,6 +202,9 @@ mod json;
|
|||
#[cfg(feature = "ipnetwork")]
|
||||
mod ipnetwork;
|
||||
|
||||
#[cfg(feature = "mac_address")]
|
||||
mod mac_address;
|
||||
|
||||
#[cfg(feature = "bit-vec")]
|
||||
mod bit_vec;
|
||||
|
||||
|
|
|
@ -75,6 +75,13 @@ pub mod ipnetwork {
|
|||
pub use ipnetwork::{IpNetwork, Ipv4Network, Ipv6Network};
|
||||
}
|
||||
|
||||
#[cfg(feature = "mac_address")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "mac_address")))]
|
||||
pub mod mac_address {
|
||||
#[doc(no_inline)]
|
||||
pub use mac_address::MacAddress;
|
||||
}
|
||||
|
||||
#[cfg(feature = "json")]
|
||||
pub use json::Json;
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@ decimal = ["sqlx-core/decimal"]
|
|||
chrono = ["sqlx-core/chrono"]
|
||||
time = ["sqlx-core/time"]
|
||||
ipnetwork = ["sqlx-core/ipnetwork"]
|
||||
mac_address = ["sqlx-core/mac_address"]
|
||||
uuid = ["sqlx-core/uuid"]
|
||||
bit-vec = ["sqlx-core/bit-vec"]
|
||||
json = ["sqlx-core/json", "serde_json"]
|
||||
|
|
|
@ -60,6 +60,9 @@ impl_database_ext! {
|
|||
#[cfg(feature = "ipnetwork")]
|
||||
sqlx::types::ipnetwork::IpNetwork,
|
||||
|
||||
#[cfg(feature = "mac_address")]
|
||||
sqlx::types::mac_address::MacAddress,
|
||||
|
||||
#[cfg(feature = "json")]
|
||||
serde_json::Value,
|
||||
|
||||
|
@ -113,6 +116,9 @@ impl_database_ext! {
|
|||
#[cfg(feature = "ipnetwork")]
|
||||
Vec<sqlx::types::ipnetwork::IpNetwork> | &[sqlx::types::ipnetwork::IpNetwork],
|
||||
|
||||
#[cfg(feature = "mac_address")]
|
||||
Vec<sqlx::types::mac_address::MacAddress> | &[sqlx::types::mac_address::MacAddress],
|
||||
|
||||
#[cfg(feature = "json")]
|
||||
Vec<serde_json::Value> | &[serde_json::Value],
|
||||
|
||||
|
|
|
@ -167,6 +167,14 @@ test_type!(ipnetwork<sqlx::types::ipnetwork::IpNetwork>(Postgres,
|
|||
.unwrap(),
|
||||
));
|
||||
|
||||
#[cfg(feature = "mac_address")]
|
||||
test_type!(mac_address<sqlx::types::mac_address::MacAddress>(Postgres,
|
||||
"'00:01:02:03:04:05'::macaddr"
|
||||
== "00:01:02:03:04:05"
|
||||
.parse::<sqlx::types::mac_address::MacAddress>()
|
||||
.unwrap()
|
||||
));
|
||||
|
||||
#[cfg(feature = "bit-vec")]
|
||||
test_type!(bitvec<sqlx::types::BitVec>(
|
||||
Postgres,
|
||||
|
@ -201,6 +209,15 @@ test_type!(ipnetwork_vec<Vec<sqlx::types::ipnetwork::IpNetwork>>(Postgres,
|
|||
]
|
||||
));
|
||||
|
||||
#[cfg(feature = "mac_address")]
|
||||
test_type!(mac_address_vec<Vec<sqlx::types::mac_address::MacAddress>>(Postgres,
|
||||
"'{01:02:03:04:05:06,FF:FF:FF:FF:FF:FF}'::inet[]"
|
||||
== vec![
|
||||
"01:02:03:04:05:06".parse::<sqlx::types::mac_address::MacAddress>().unwrap(),
|
||||
"FF:FF:FF:FF:FF:FF".parse::<sqlx::types::mac_address::MacAddress>().unwrap()
|
||||
]
|
||||
));
|
||||
|
||||
#[cfg(feature = "chrono")]
|
||||
mod chrono {
|
||||
use super::*;
|
||||
|
|
Loading…
Reference in a new issue