forked from Proxmox/proxmox
add proxmox-uuid crate
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
77dc52c047
commit
bd67ccc1b3
@ -5,6 +5,7 @@ members = [
|
||||
"proxmox-http",
|
||||
"proxmox-sortable-macro",
|
||||
"proxmox-tfa",
|
||||
"proxmox-uuid",
|
||||
]
|
||||
exclude = [
|
||||
"build",
|
||||
|
3
Makefile
3
Makefile
@ -5,7 +5,8 @@ CRATES = \
|
||||
proxmox-api-macro \
|
||||
proxmox-http \
|
||||
proxmox-sortable-macro \
|
||||
proxmox-tfa
|
||||
proxmox-tfa \
|
||||
proxmox-uuid
|
||||
|
||||
# By default we just run checks:
|
||||
.PHONY: all
|
||||
|
20
proxmox-uuid/Cargo.toml
Normal file
20
proxmox-uuid/Cargo.toml
Normal file
@ -0,0 +1,20 @@
|
||||
[package]
|
||||
name = "proxmox-uuid"
|
||||
version = "1.0.0"
|
||||
authors = ["Proxmox Support Team <support@proxmox.com>"]
|
||||
edition = "2018"
|
||||
license = "AGPL-3"
|
||||
description = "bindings for libuuid with optional serde support"
|
||||
|
||||
exclude = [ "debian" ]
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
serde = { version = "1.0", optional = true }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
[dev-dependencies]
|
||||
serde = "1.0"
|
||||
serde_json = "1.0"
|
5
proxmox-uuid/debian/changelog
Normal file
5
proxmox-uuid/debian/changelog
Normal file
@ -0,0 +1,5 @@
|
||||
rust-proxmox-uuid (1.0.0-1) stable; urgency=medium
|
||||
|
||||
* initial split out of `librust-proxmox-dev`
|
||||
|
||||
-- Proxmox Support Team <support@proxmox.com> Mon, 04 Oct 2021 11:38:53 +0200
|
49
proxmox-uuid/debian/control
Normal file
49
proxmox-uuid/debian/control
Normal file
@ -0,0 +1,49 @@
|
||||
Source: rust-proxmox-uuid
|
||||
Section: rust
|
||||
Priority: optional
|
||||
Build-Depends: debhelper (>= 12),
|
||||
dh-cargo (>= 24),
|
||||
cargo:native <!nocheck>,
|
||||
rustc:native <!nocheck>,
|
||||
libstd-rust-dev <!nocheck>,
|
||||
librust-libc-0.2+default-dev <!nocheck>
|
||||
Maintainer: Proxmox Support Team <support@proxmox.com>
|
||||
Standards-Version: 4.5.1
|
||||
Vcs-Git: git://git.proxmox.com/git/proxmox.git
|
||||
Vcs-Browser: https://git.proxmox.com/?p=proxmox.git
|
||||
Rules-Requires-Root: no
|
||||
|
||||
Package: librust-proxmox-uuid-dev
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
Depends:
|
||||
${misc:Depends},
|
||||
librust-libc-0.2+default-dev
|
||||
Suggests:
|
||||
librust-proxmox-uuid+serde-dev (= ${binary:Version})
|
||||
Provides:
|
||||
librust-proxmox-uuid+default-dev (= ${binary:Version}),
|
||||
librust-proxmox-uuid-1-dev (= ${binary:Version}),
|
||||
librust-proxmox-uuid-1+default-dev (= ${binary:Version}),
|
||||
librust-proxmox-uuid-1.0-dev (= ${binary:Version}),
|
||||
librust-proxmox-uuid-1.0+default-dev (= ${binary:Version}),
|
||||
librust-proxmox-uuid-1.0.0-dev (= ${binary:Version}),
|
||||
librust-proxmox-uuid-1.0.0+default-dev (= ${binary:Version})
|
||||
Description: Bindings for libuuid with optional serde support - Rust source code
|
||||
This package contains the source for the Rust proxmox-uuid crate, packaged by
|
||||
debcargo for use with cargo and dh-cargo.
|
||||
|
||||
Package: librust-proxmox-uuid+serde-dev
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
Depends:
|
||||
${misc:Depends},
|
||||
librust-proxmox-uuid-dev (= ${binary:Version}),
|
||||
librust-serde-1+default-dev
|
||||
Provides:
|
||||
librust-proxmox-uuid-1+serde-dev (= ${binary:Version}),
|
||||
librust-proxmox-uuid-1.0+serde-dev (= ${binary:Version}),
|
||||
librust-proxmox-uuid-1.0.0+serde-dev (= ${binary:Version})
|
||||
Description: Bindings for libuuid with optional serde support - feature "serde"
|
||||
This metapackage enables feature "serde" for the Rust proxmox-uuid crate, by
|
||||
pulling in any additional dependencies needed by that feature.
|
16
proxmox-uuid/debian/copyright
Normal file
16
proxmox-uuid/debian/copyright
Normal file
@ -0,0 +1,16 @@
|
||||
Copyright (C) 2021 Proxmox Server Solutions GmbH
|
||||
|
||||
This software is written by Proxmox Server Solutions GmbH <support@proxmox.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
7
proxmox-uuid/debian/debcargo.toml
Normal file
7
proxmox-uuid/debian/debcargo.toml
Normal file
@ -0,0 +1,7 @@
|
||||
overlay = "."
|
||||
crate_src_path = ".."
|
||||
maintainer = "Proxmox Support Team <support@proxmox.com>"
|
||||
|
||||
[source]
|
||||
vcs_git = "git://git.proxmox.com/git/proxmox.git"
|
||||
vcs_browser = "https://git.proxmox.com/?p=proxmox.git"
|
@ -3,11 +3,6 @@
|
||||
use std::borrow::{Borrow, BorrowMut};
|
||||
use std::fmt;
|
||||
|
||||
use anyhow::{bail, Error};
|
||||
use serde::{Serialize, Serializer};
|
||||
|
||||
use crate::tools::parse::hex_nibble;
|
||||
|
||||
#[link(name = "uuid")]
|
||||
extern "C" {
|
||||
fn uuid_generate(out: *mut [u8; 16]);
|
||||
@ -15,10 +10,32 @@ extern "C" {
|
||||
fn uuid_unparse_upper(input: *const [u8; 16], out: *mut u8);
|
||||
}
|
||||
|
||||
/// An error parsing a uuid from a string.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct UuidError;
|
||||
|
||||
impl fmt::Display for UuidError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.write_str("bad uuid format")
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for UuidError {}
|
||||
|
||||
/// Check for hex digits.
|
||||
fn hex_digit(b: u8) -> Result<u8, UuidError> {
|
||||
Ok(match b {
|
||||
b'0'..=b'9' => b - b'0',
|
||||
b'a'..=b'f' => b - b'a' + 0xA,
|
||||
b'A'..=b'F' => b - b'A' + 0xA,
|
||||
_ => return Err(UuidError),
|
||||
})
|
||||
}
|
||||
|
||||
/// Uuid generated with the system's native libuuid.
|
||||
///
|
||||
/// ```
|
||||
/// use proxmox::tools::uuid::Uuid;
|
||||
/// use proxmox_uuid::Uuid;
|
||||
///
|
||||
/// let uuid = Uuid::generate();
|
||||
/// println!("Generated uuid: {}", uuid);
|
||||
@ -58,7 +75,7 @@ impl Uuid {
|
||||
/// Parse a uuid in optionally-hyphenated format.
|
||||
///
|
||||
/// ```
|
||||
/// use proxmox::tools::uuid::Uuid;
|
||||
/// use proxmox_uuid::Uuid;
|
||||
///
|
||||
/// let gen = Uuid::generate();
|
||||
/// let text = format!("{}", gen);
|
||||
@ -69,7 +86,7 @@ impl Uuid {
|
||||
/// let uuid2: Uuid = "65b85639-78d7-4330-85c6-39502b2f9b01".parse().unwrap();
|
||||
/// assert_eq!(uuid1, uuid2);
|
||||
/// ```
|
||||
pub fn parse_str(src: &str) -> Result<Self, Error> {
|
||||
pub fn parse_str(src: &str) -> Result<Self, UuidError> {
|
||||
use std::alloc::{alloc, Layout};
|
||||
let uuid: *mut [u8; 16] = unsafe { alloc(Layout::new::<[u8; 16]>()) as *mut [u8; 16] };
|
||||
if src.len() == 36 {
|
||||
@ -78,31 +95,31 @@ impl Uuid {
|
||||
let uuid: &mut [u8] = unsafe { &mut (*uuid)[..] };
|
||||
let src = src.as_bytes();
|
||||
if src[8] != b'-' || src[13] != b'-' || src[18] != b'-' || src[23] != b'-' {
|
||||
bail!("failed to parse uuid");
|
||||
return Err(UuidError);
|
||||
}
|
||||
for i in 0..4 {
|
||||
uuid[i] = hex_nibble(src[2 * i])? << 4 | hex_nibble(src[2 * i + 1])?;
|
||||
uuid[i] = hex_digit(src[2 * i])? << 4 | hex_digit(src[2 * i + 1])?;
|
||||
}
|
||||
for i in 4..6 {
|
||||
uuid[i] = hex_nibble(src[2 * i + 1])? << 4 | hex_nibble(src[2 * i + 2])?;
|
||||
uuid[i] = hex_digit(src[2 * i + 1])? << 4 | hex_digit(src[2 * i + 2])?;
|
||||
}
|
||||
for i in 6..8 {
|
||||
uuid[i] = hex_nibble(src[2 * i + 2])? << 4 | hex_nibble(src[2 * i + 3])?;
|
||||
uuid[i] = hex_digit(src[2 * i + 2])? << 4 | hex_digit(src[2 * i + 3])?;
|
||||
}
|
||||
for i in 8..10 {
|
||||
uuid[i] = hex_nibble(src[2 * i + 3])? << 4 | hex_nibble(src[2 * i + 4])?;
|
||||
uuid[i] = hex_digit(src[2 * i + 3])? << 4 | hex_digit(src[2 * i + 4])?;
|
||||
}
|
||||
for i in 10..16 {
|
||||
uuid[i] = hex_nibble(src[2 * i + 4])? << 4 | hex_nibble(src[2 * i + 5])?;
|
||||
uuid[i] = hex_digit(src[2 * i + 4])? << 4 | hex_digit(src[2 * i + 5])?;
|
||||
}
|
||||
} else if src.len() == 32 {
|
||||
let uuid: &mut [u8] = unsafe { &mut (*uuid)[..] };
|
||||
let src = src.as_bytes();
|
||||
for i in 0..16 {
|
||||
uuid[i] = hex_nibble(src[2 * i])? << 4 | hex_nibble(src[2 * i + 1])?;
|
||||
uuid[i] = hex_digit(src[2 * i])? << 4 | hex_digit(src[2 * i + 1])?;
|
||||
}
|
||||
} else {
|
||||
bail!("unrecognized uuid format");
|
||||
return Err(UuidError);
|
||||
}
|
||||
Ok(Self(unsafe { Box::from_raw(uuid) }))
|
||||
}
|
||||
@ -185,17 +202,18 @@ impl fmt::UpperHex for Uuid {
|
||||
}
|
||||
|
||||
impl std::str::FromStr for Uuid {
|
||||
type Err = Error;
|
||||
type Err = UuidError;
|
||||
|
||||
fn from_str(src: &str) -> Result<Self, Error> {
|
||||
fn from_str(src: &str) -> Result<Self, UuidError> {
|
||||
Self::parse_str(src)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for Uuid {
|
||||
#[cfg(feature = "serde")]
|
||||
impl serde::Serialize for Uuid {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
S: serde::Serializer,
|
||||
{
|
||||
let mut buf = [0u8; 37];
|
||||
unsafe {
|
||||
@ -205,10 +223,45 @@ impl Serialize for Uuid {
|
||||
}
|
||||
}
|
||||
|
||||
forward_deserialize_to_from_str!(Uuid);
|
||||
//forward_deserialize_to_from_str!(Uuid);
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de> serde::Deserialize<'de> for Uuid {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Uuid, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
use serde::de::Error;
|
||||
|
||||
struct ForwardToStrVisitor;
|
||||
|
||||
impl<'a> serde::de::Visitor<'a> for ForwardToStrVisitor {
|
||||
type Value = Uuid;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("a valid uuid as a string")
|
||||
}
|
||||
|
||||
fn visit_str<E: Error>(self, v: &str) -> Result<Uuid, E> {
|
||||
v.parse::<Uuid>()
|
||||
.map_err(|err| Error::custom(err.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_str(ForwardToStrVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_uuid() {
|
||||
let uuid = Uuid::generate();
|
||||
let ser: String = uuid.to_string();
|
||||
let de: Uuid = ser.parse().expect("failed to parse uuid");
|
||||
assert_eq!(uuid, de);
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn test_uuid_serde() {
|
||||
let uuid = Uuid::generate();
|
||||
let ser: String = serde_json::to_string(&uuid).expect("failed to serialize uuid");
|
||||
let de: Uuid = serde_json::from_str(&ser).expect("failed to deserialize uuid");
|
@ -18,13 +18,9 @@ pub mod mmap;
|
||||
pub mod parse;
|
||||
pub mod serde;
|
||||
pub mod time;
|
||||
pub mod uuid;
|
||||
pub mod vec;
|
||||
pub mod systemd;
|
||||
|
||||
#[doc(inline)]
|
||||
pub use uuid::Uuid;
|
||||
|
||||
#[doc(inline)]
|
||||
pub use as_any::AsAny;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user