diff --git a/Cargo.toml b/Cargo.toml index 20c4bca8..47e2c7b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ members = [ "proxmox-api-macro", "proxmox-borrow", "proxmox-http", + "proxmox-lang", "proxmox-sortable-macro", "proxmox-tfa", "proxmox-time", diff --git a/Makefile b/Makefile index 08468cdc..205528b2 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ CRATES = \ proxmox-api-macro \ proxmox-borrow \ proxmox-http \ + proxmox-lang \ proxmox-sortable-macro \ proxmox-tfa \ proxmox-time \ diff --git a/proxmox-lang/Cargo.toml b/proxmox-lang/Cargo.toml new file mode 100644 index 00000000..4b4bd9f2 --- /dev/null +++ b/proxmox-lang/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "proxmox-lang" +version = "1.0.0" +authors = ["Proxmox Support Team "] +edition = "2018" +license = "AGPL-3" +description = "simple rust language utilities such as try_block, which have no dependencies" + +exclude = [ "debian" ] + +[dependencies] diff --git a/proxmox-lang/debian/changelog b/proxmox-lang/debian/changelog new file mode 100644 index 00000000..f232ff5f --- /dev/null +++ b/proxmox-lang/debian/changelog @@ -0,0 +1,5 @@ +rust-proxmox-lang (1.0.0-1) stable; urgency=medium + + * initial split out of `librust-proxmox-dev` + + -- Proxmox Support Team Wed, 06 Oct 2021 11:04:36 +0200 diff --git a/proxmox-lang/debian/control b/proxmox-lang/debian/control new file mode 100644 index 00000000..73f7bbe6 --- /dev/null +++ b/proxmox-lang/debian/control @@ -0,0 +1,30 @@ +Source: rust-proxmox-lang +Section: rust +Priority: optional +Build-Depends: debhelper (>= 12), + dh-cargo (>= 24), + cargo:native , + rustc:native , + libstd-rust-dev +Maintainer: Proxmox Support Team +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-lang-dev +Architecture: any +Multi-Arch: same +Depends: + ${misc:Depends} +Provides: + librust-proxmox-lang+default-dev (= ${binary:Version}), + librust-proxmox-lang-1-dev (= ${binary:Version}), + librust-proxmox-lang-1+default-dev (= ${binary:Version}), + librust-proxmox-lang-1.0-dev (= ${binary:Version}), + librust-proxmox-lang-1.0+default-dev (= ${binary:Version}), + librust-proxmox-lang-1.0.0-dev (= ${binary:Version}), + librust-proxmox-lang-1.0.0+default-dev (= ${binary:Version}) +Description: Simple rust language utilities such as try_block, which have no dependencies - Rust source code + This package contains the source for the Rust proxmox-lang crate, packaged by + debcargo for use with cargo and dh-cargo. diff --git a/proxmox-lang/debian/copyright b/proxmox-lang/debian/copyright new file mode 100644 index 00000000..5661ef60 --- /dev/null +++ b/proxmox-lang/debian/copyright @@ -0,0 +1,16 @@ +Copyright (C) 2021 Proxmox Server Solutions GmbH + +This software is written by Proxmox Server Solutions GmbH + +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 . diff --git a/proxmox-lang/debian/debcargo.toml b/proxmox-lang/debian/debcargo.toml new file mode 100644 index 00000000..b7864cdb --- /dev/null +++ b/proxmox-lang/debian/debcargo.toml @@ -0,0 +1,7 @@ +overlay = "." +crate_src_path = ".." +maintainer = "Proxmox Support Team " + +[source] +vcs_git = "git://git.proxmox.com/git/proxmox.git" +vcs_browser = "https://git.proxmox.com/?p=proxmox.git" diff --git a/proxmox/src/tools/constnamedbitmap.rs b/proxmox-lang/src/constnamedbitmap.rs similarity index 97% rename from proxmox/src/tools/constnamedbitmap.rs rename to proxmox-lang/src/constnamedbitmap.rs index eb1ba871..df931bd8 100644 --- a/proxmox/src/tools/constnamedbitmap.rs +++ b/proxmox-lang/src/constnamedbitmap.rs @@ -4,7 +4,7 @@ /// /// Example: /// ``` -/// # use proxmox::constnamedbitmap; +/// # use proxmox_lang::constnamedbitmap; /// /// constnamedbitmap! { /// /// A list of privileges diff --git a/proxmox-lang/src/lib.rs b/proxmox-lang/src/lib.rs new file mode 100644 index 00000000..14b8e6b0 --- /dev/null +++ b/proxmox-lang/src/lib.rs @@ -0,0 +1,92 @@ +//! Rust language related helpers. +//! +//! This provides some macros for features which are not yet available in the language, or +//! sometimes also types from nightly `std` which are simple enough to do just haven't been +//! bikeshedded and stabilized in the standard library yet. + +mod constnamedbitmap; + +pub mod ops; + +/// Macro to write error-handling blocks (like perl eval {}) +/// +/// #### Example: +/// ``` +/// # use proxmox_lang::try_block; +/// # macro_rules! format_err { +/// # ($($msg:tt)+) => { format!($($msg)+) } +/// # } +/// # macro_rules! bail { +/// # ($($msg:tt)+) => { return Err(format_err!($($msg)+)); } +/// # } +/// # let some_condition = false; +/// let result = try_block!({ +/// if (some_condition) { +/// bail!("some error"); +/// } +/// Ok(()) +/// }) +/// .map_err(|e| format_err!("my try block returned an error - {}", e)); +/// ``` + +#[macro_export] +macro_rules! try_block { + { $($token:tt)* } => {{ (|| -> Result<_,_> { $($token)* })() }} +} + +/// Statically assert the size of a type at compile time. +/// +/// This should compile: +/// ``` +/// # use proxmox_lang::static_assert_size; +/// #[repr(C)] +/// struct Stuff { +/// value: [u8; 32] +/// } +/// static_assert_size!(Stuff, 32); +/// ``` +/// +/// This should fail to compile: +/// ```compile_fail +/// # use proxmox_lang::static_assert_size; +/// #[repr(C)] +/// struct Stuff { +/// value: [u8; 32] +/// } +/// static_assert_size!(Stuff, 128); +/// ``` +#[macro_export] +macro_rules! static_assert_size { + ($ty:ty, $size:expr) => { + const _: fn() -> () = || { + let _ = ::std::mem::transmute::<[u8; $size], $ty>; + }; + }; +} + +/// Evaluates to the offset (in bytes) of a given member within a struct +/// +/// ``` +/// # use proxmox_lang::offsetof; +/// +/// #[repr(C)] +/// struct Stuff { +/// first: u32, +/// second: u32, +/// } +/// +/// assert_eq!(offsetof!(Stuff, second), 4); +/// +/// ``` +// FIXME: With 1.56 we get `const transmute` which may help making this usable `const fn` as we can +// avoid dereferencing the raw pointer by transmuting `0usize` into a proper reference instead. +// +// So with 1.56, do this instead: +// +// unsafe { &(std::mem::transmute::<_, &$ty>(0usize).$field) as *const _ as usize } +#[macro_export] +macro_rules! offsetof { + ($ty:ty, $field:ident) => { + unsafe { &(*(std::ptr::null::<$ty>())).$field as *const _ as usize } + }; +} diff --git a/proxmox-lang/src/ops.rs b/proxmox-lang/src/ops.rs new file mode 100644 index 00000000..6fd70d7e --- /dev/null +++ b/proxmox-lang/src/ops.rs @@ -0,0 +1,14 @@ +//! std::ops extensions + +/// Modeled after the nightly `std::ops::ControlFlow`. +/// +/// To be removed with rust 1.55. +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum ControlFlow { + Continue(C), + Break(B), +} + +impl ControlFlow { + pub const CONTINUE: ControlFlow = ControlFlow::Continue(()); +} diff --git a/proxmox/src/tools/mod.rs b/proxmox/src/tools/mod.rs index 17a5b6bd..f4f78dcb 100644 --- a/proxmox/src/tools/mod.rs +++ b/proxmox/src/tools/mod.rs @@ -8,7 +8,6 @@ use lazy_static::lazy_static; pub mod as_any; pub mod byte_buffer; pub mod common_regex; -pub mod constnamedbitmap; pub mod email; pub mod fd; pub mod fs; @@ -22,65 +21,6 @@ pub mod systemd; #[doc(inline)] pub use as_any::AsAny; -/// Evaluates to the offset (in bytes) of a given member within a struct -#[macro_export] -macro_rules! offsetof { - ($ty:ty, $field:ident) => { - unsafe { &(*(std::ptr::null::<$ty>())).$field as *const _ as usize } - }; -} - -/// Statically assert the size of a type at compile time. -/// -/// This should compile: -/// ``` -/// # use proxmox::static_assert_size; -/// #[repr(C)] -/// struct Stuff { -/// value: [u8; 32] -/// } -/// static_assert_size!(Stuff, 32); -/// ``` -/// -/// This should fail to compile: -/// ```compile_fail -/// # use proxmox::static_assert_size; -/// #[repr(C)] -/// struct Stuff { -/// value: [u8; 32] -/// } -/// static_assert_size!(Stuff, 128); -/// ``` -#[macro_export] -macro_rules! static_assert_size { - ($ty:ty, $size:expr) => { - const _: fn() -> () = || { - let _ = ::std::mem::transmute::<[u8; $size], $ty>; - }; - }; -} - -/// Macro to write error-handling blocks (like perl eval {}) -/// -/// #### Example: -/// ``` -/// # use proxmox::try_block; -/// # use anyhow::*; -/// # let some_condition = false; -/// let result = try_block!({ -/// if (some_condition) { -/// bail!("some error"); -/// } -/// Ok(()) -/// }) -/// .map_err(|e| format_err!("my try block returned an error - {}", e)); -/// ``` - -#[macro_export] -macro_rules! try_block { - { $($token:tt)* } => {{ (|| -> Result<_,_> { $($token)* })() }} -} - const HEX_CHARS: &[u8; 16] = b"0123456789abcdef"; /// Helper to provide a `Display` for arbitrary byte slices.