mirror of
https://gitlab.com/fabinfra/fabaccess/bffh.git
synced 2024-11-23 15:17:57 +01:00
Implement new traits structure
This commit is contained in:
parent
5400d7f799
commit
2acf35d54d
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -489,6 +489,15 @@ version = "0.21.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
|
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bffh-impl"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.58",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitfield"
|
name = "bitfield"
|
||||||
version = "0.13.2"
|
version = "0.13.2"
|
||||||
@ -1052,6 +1061,7 @@ dependencies = [
|
|||||||
"async-process",
|
"async-process",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"backtrace",
|
"backtrace",
|
||||||
|
"bffh-impl",
|
||||||
"capnp",
|
"capnp",
|
||||||
"capnp-rpc",
|
"capnp-rpc",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
@ -44,6 +44,9 @@ miette = { version = "4.7.1", features = ["fancy"] }
|
|||||||
thiserror = "1.0.31"
|
thiserror = "1.0.31"
|
||||||
toml = "0.5.8"
|
toml = "0.5.8"
|
||||||
|
|
||||||
|
# Compilation proc-macros
|
||||||
|
bffh-impl = { path = "modules/impl" }
|
||||||
|
|
||||||
# Well-known paths/dirs for e.g. cache
|
# Well-known paths/dirs for e.g. cache
|
||||||
dirs = "4.0.0"
|
dirs = "4.0.0"
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit cae56b00842362bd4599187b171ddf8a1030e248
|
Subproject commit 879bc578b20433c527cea34a5821cdccec9ee587
|
@ -30,6 +30,7 @@ mod resources;
|
|||||||
mod permissionsystem;
|
mod permissionsystem;
|
||||||
mod user;
|
mod user;
|
||||||
mod user_system;
|
mod user_system;
|
||||||
|
mod traits;
|
||||||
|
|
||||||
pub struct APIServer {
|
pub struct APIServer {
|
||||||
executor: Executor<'static>,
|
executor: Executor<'static>,
|
||||||
|
@ -3,9 +3,16 @@ use crate::resources::modules::fabaccess::{ArchivedStatus, Status};
|
|||||||
use crate::resources::Resource;
|
use crate::resources::Resource;
|
||||||
use crate::session::SessionHandle;
|
use crate::session::SessionHandle;
|
||||||
use api::resource_capnp::resource;
|
use api::resource_capnp::resource;
|
||||||
use api::claim_capnp::claimable;
|
use api::claim_capnp::{claimable, claim};
|
||||||
|
use api::notify_capnp::notifiable;
|
||||||
|
use api::owned_capnp::owned;
|
||||||
|
use api::projects_capnp::project;
|
||||||
use capnp::capability::Promise;
|
use capnp::capability::Promise;
|
||||||
|
use capnp::Error;
|
||||||
use capnp_rpc::pry;
|
use capnp_rpc::pry;
|
||||||
|
use api::claim_capnp::claim::{DisownParams, DisownResults, TraitsParams, TraitsResults};
|
||||||
|
use api::claim_capnp::claimable::{ClaimParams, ClaimResults};
|
||||||
|
use api::owned_capnp::owned::{GetUserParams, GetUserResults};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Machine {
|
pub struct Machine {
|
||||||
@ -26,5 +33,38 @@ impl Machine {
|
|||||||
|
|
||||||
|
|
||||||
impl claimable::Server for Machine {
|
impl claimable::Server for Machine {
|
||||||
|
fn claim(&mut self, params: ClaimParams, mut results: ClaimResults) -> Promise<(), Error> {
|
||||||
|
let project = params.get().and_then(|r| r.get_project()).ok();
|
||||||
|
//self.resource.try_claim();
|
||||||
|
let claim = Claim::new(self.session.clone(), project, self.resource.clone());
|
||||||
|
pry!(results.get().set_ok(capnp_rpc::new_client(claim)));
|
||||||
|
Promise::ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Claim {
|
||||||
|
session: SessionHandle,
|
||||||
|
project: Option<project::Client>,
|
||||||
|
resource: Resource,
|
||||||
|
}
|
||||||
|
impl Claim {
|
||||||
|
fn new(session: SessionHandle, project: Option<project::Client>, resource: Resource) -> Self {
|
||||||
|
Self { session, project, resource }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl notifiable::Server for Claim {}
|
||||||
|
|
||||||
|
impl owned::Server for Claim {
|
||||||
|
fn get_user(&mut self, _: GetUserParams, mut results: GetUserResults) -> Promise<(), Error> {
|
||||||
|
let owner = User::new_self(self.session.clone());
|
||||||
|
results.get().set_owner(capnp_rpc::new_client(owner));
|
||||||
|
Promise::ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl claim::Server for Claim {
|
||||||
|
fn traits(&mut self, _: TraitsParams, _: TraitsResults) -> Promise<(), Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
}
|
}
|
7
bffhd/capnp/traits/claimable.rs
Normal file
7
bffhd/capnp/traits/claimable.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
use crate::oid;
|
||||||
|
use crate::utils::oid::ObjectIdentifier;
|
||||||
|
use api::traits::claimable_capnp::trait_claimable;
|
||||||
|
|
||||||
|
pub const CLAIMABLE_TRAIT_ID: ObjectIdentifier = oid!(1.3.6.1.4.1.61783.612.1.0);
|
||||||
|
|
||||||
|
|
2
bffhd/capnp/traits/mod.rs
Normal file
2
bffhd/capnp/traits/mod.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
mod claimable;
|
||||||
|
mod powerable;
|
4
bffhd/capnp/traits/powerable.rs
Normal file
4
bffhd/capnp/traits/powerable.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
use crate::oid;
|
||||||
|
use crate::utils::oid::ObjectIdentifier;
|
||||||
|
|
||||||
|
pub const TRAIT_ID_POWERABLE: ObjectIdentifier = oid!(1.3.6.1.4.1.61783.612.1.1);
|
@ -132,7 +132,7 @@ pub trait SerializeDynOid {
|
|||||||
///
|
///
|
||||||
/// This OID will be serialized alongside the trait object and is used to retrieve the
|
/// This OID will be serialized alongside the trait object and is used to retrieve the
|
||||||
/// correct vtable when loading the state from DB.
|
/// correct vtable when loading the state from DB.
|
||||||
fn archived_type_oid(&self) -> &'static ObjectIdentifier;
|
fn archived_type_oid(&self) -> &'static ObjectIdentifier<'static>;
|
||||||
|
|
||||||
/// Serialize this type into a [`DynSerializer`](trait@DynSerializer)
|
/// Serialize this type into a [`DynSerializer`](trait@DynSerializer)
|
||||||
fn serialize_dynoid(&self, serializer: &mut dyn DynSerializer) -> Result<usize, DynError>;
|
fn serialize_dynoid(&self, serializer: &mut dyn DynSerializer) -> Result<usize, DynError>;
|
||||||
@ -144,7 +144,7 @@ pub trait SerializeDynOid {
|
|||||||
/// providing the OID that is serialized alongside the state object to be able to correctly cast
|
/// providing the OID that is serialized alongside the state object to be able to correctly cast
|
||||||
/// it when accessing state from the DB.
|
/// it when accessing state from the DB.
|
||||||
pub trait TypeOid {
|
pub trait TypeOid {
|
||||||
fn type_oid() -> &'static ObjectIdentifier;
|
fn type_oid() -> &'static ObjectIdentifier<'static>;
|
||||||
fn type_name() -> &'static str;
|
fn type_name() -> &'static str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +153,7 @@ where
|
|||||||
T: for<'a> Serialize<dyn DynSerializer + 'a>,
|
T: for<'a> Serialize<dyn DynSerializer + 'a>,
|
||||||
T::Archived: TypeOid,
|
T::Archived: TypeOid,
|
||||||
{
|
{
|
||||||
fn archived_type_oid(&self) -> &'static ObjectIdentifier {
|
fn archived_type_oid(&self) -> &'static ObjectIdentifier<'static> {
|
||||||
Archived::<T>::type_oid()
|
Archived::<T>::type_oid()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ impl ArchivePointee for dyn ArchivedStateValue {
|
|||||||
|
|
||||||
impl ArchiveUnsized for dyn SerializeStateValue {
|
impl ArchiveUnsized for dyn SerializeStateValue {
|
||||||
type Archived = dyn ArchivedStateValue;
|
type Archived = dyn ArchivedStateValue;
|
||||||
type MetadataResolver = <ObjectIdentifier as Archive>::Resolver;
|
type MetadataResolver = <ObjectIdentifier<'static> as Archive>::Resolver;
|
||||||
|
|
||||||
unsafe fn resolve_metadata(
|
unsafe fn resolve_metadata(
|
||||||
&self,
|
&self,
|
||||||
@ -203,7 +203,7 @@ impl<S: ScratchSpace + Serializer + ?Sized> SerializeUnsized<S> for dyn Serializ
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ArchivedStateValueMetadata {
|
pub struct ArchivedStateValueMetadata {
|
||||||
pub type_oid: Archived<ObjectIdentifier>,
|
pub type_oid: Archived<ObjectIdentifier<'static>>,
|
||||||
vtable_cache: AtomicUsize,
|
vtable_cache: AtomicUsize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
//! [Object Identifiers]: https://en.wikipedia.org/wiki/Object_identifier
|
//! [Object Identifiers]: https://en.wikipedia.org/wiki/Object_identifier
|
||||||
//! [ITU]: https://en.wikipedia.org/wiki/International_Telecommunications_Union
|
//! [ITU]: https://en.wikipedia.org/wiki/International_Telecommunications_Union
|
||||||
|
|
||||||
|
use std::borrow::Cow;
|
||||||
use crate::utils::varint::VarU128;
|
use crate::utils::varint::VarU128;
|
||||||
use rkyv::ser::Serializer;
|
use rkyv::ser::Serializer;
|
||||||
use rkyv::vec::{ArchivedVec, VecResolver};
|
use rkyv::vec::{ArchivedVec, VecResolver};
|
||||||
@ -114,16 +115,16 @@ pub enum ObjectIdentifierError {
|
|||||||
/// Object Identifier (OID)
|
/// Object Identifier (OID)
|
||||||
#[derive(Clone, Eq, PartialEq, Hash)]
|
#[derive(Clone, Eq, PartialEq, Hash)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct ObjectIdentifier {
|
pub struct ObjectIdentifier<'a> {
|
||||||
nodes: Box<[u8]>,
|
nodes: Cow<'a, [u8]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectIdentifier {
|
impl<'a> ObjectIdentifier<'a> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub const fn new_unchecked(nodes: Box<[u8]>) -> Self {
|
pub const fn new_unchecked(nodes: Cow<'a, [u8]>) -> Self {
|
||||||
Self { nodes }
|
Self { nodes }
|
||||||
}
|
}
|
||||||
pub fn from_box(nodes: Box<[u8]>) -> Result<Self, ObjectIdentifierError> {
|
pub fn from_box(nodes: Cow<'a, [u8]>) -> Result<Self, ObjectIdentifierError> {
|
||||||
if nodes.len() < 1 {
|
if nodes.len() < 1 {
|
||||||
return Err(ObjectIdentifierError::IllegalRootNode);
|
return Err(ObjectIdentifierError::IllegalRootNode);
|
||||||
};
|
};
|
||||||
@ -167,7 +168,7 @@ impl ObjectIdentifier {
|
|||||||
vec.extend_from_slice(var.as_bytes())
|
vec.extend_from_slice(var.as_bytes())
|
||||||
}
|
}
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
nodes: vec.into_boxed_slice(),
|
nodes: Cow::from(vec),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,28 +176,29 @@ impl ObjectIdentifier {
|
|||||||
pub fn root(&self) -> Result<ObjectIdentifierRoot, ObjectIdentifierError> {
|
pub fn root(&self) -> Result<ObjectIdentifierRoot, ObjectIdentifierError> {
|
||||||
ObjectIdentifierRoot::try_from(self.nodes[0] / 40)
|
ObjectIdentifierRoot::try_from(self.nodes[0] / 40)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub const fn first_node(&self) -> u8 {
|
pub fn first_node(&self) -> u8 {
|
||||||
self.nodes[0] % 40
|
self.nodes.as_ref()[0] % 40
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn child_nodes(&self) -> &[u8] {
|
pub fn child_nodes(&self) -> &[u8] {
|
||||||
&self.nodes[1..]
|
&self.nodes[1..]
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub const fn as_bytes(&self) -> &[u8] {
|
pub fn as_bytes(&self) -> &[u8] {
|
||||||
&self.nodes
|
&self.nodes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for ObjectIdentifier {
|
impl Deref for ObjectIdentifier<'_> {
|
||||||
type Target = [u8];
|
type Target = [u8];
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.nodes
|
&self.nodes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for ObjectIdentifier {
|
impl FromStr for ObjectIdentifier<'static> {
|
||||||
type Err = ObjectIdentifierError;
|
type Err = ObjectIdentifierError;
|
||||||
|
|
||||||
fn from_str(value: &str) -> Result<Self, Self::Err> {
|
fn from_str(value: &str) -> Result<Self, Self::Err> {
|
||||||
@ -230,13 +232,13 @@ impl FromStr for ObjectIdentifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ObjectIdentifier {
|
impl fmt::Display for ObjectIdentifier<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
let show: String = self.into();
|
let show: String = self.into();
|
||||||
write!(f, "{}", show)
|
write!(f, "{}", show)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl fmt::Debug for ObjectIdentifier {
|
impl fmt::Debug for ObjectIdentifier<'_> {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
let show: String = self.into();
|
let show: String = self.into();
|
||||||
write!(f, "{}", show)
|
write!(f, "{}", show)
|
||||||
@ -266,7 +268,7 @@ impl fmt::Debug for ArchivedObjectIdentifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Archive for ObjectIdentifier {
|
impl Archive for ObjectIdentifier<'_> {
|
||||||
type Archived = ArchivedObjectIdentifier;
|
type Archived = ArchivedObjectIdentifier;
|
||||||
type Resolver = VecResolver;
|
type Resolver = VecResolver;
|
||||||
|
|
||||||
@ -275,7 +277,7 @@ impl Archive for ObjectIdentifier {
|
|||||||
ArchivedVec::resolve_from_slice(self.nodes.as_ref(), pos + oid_pos, resolver, oid_out);
|
ArchivedVec::resolve_from_slice(self.nodes.as_ref(), pos + oid_pos, resolver, oid_out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Archive for &'static ObjectIdentifier {
|
impl Archive for &'static ObjectIdentifier<'_> {
|
||||||
type Archived = ArchivedObjectIdentifier;
|
type Archived = ArchivedObjectIdentifier;
|
||||||
type Resolver = VecResolver;
|
type Resolver = VecResolver;
|
||||||
|
|
||||||
@ -285,7 +287,7 @@ impl Archive for &'static ObjectIdentifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Serializer + ?Sized> Serialize<S> for ObjectIdentifier
|
impl<S: Serializer + ?Sized> Serialize<S> for ObjectIdentifier<'_>
|
||||||
where
|
where
|
||||||
[u8]: rkyv::SerializeUnsized<S>,
|
[u8]: rkyv::SerializeUnsized<S>,
|
||||||
{
|
{
|
||||||
@ -304,8 +306,8 @@ fn parse_string_first_node(first_child_node: &str) -> Result<u8, ObjectIdentifie
|
|||||||
Ok(first_child_node)
|
Ok(first_child_node)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectIdentifier {
|
impl ObjectIdentifier<'static> {
|
||||||
fn from_string<S>(value: S) -> Result<ObjectIdentifier, ObjectIdentifierError>
|
fn from_string<S>(value: S) -> Result<Self, ObjectIdentifierError>
|
||||||
where
|
where
|
||||||
S: AsRef<str>,
|
S: AsRef<str>,
|
||||||
{
|
{
|
||||||
@ -350,55 +352,55 @@ fn convert_to_string(nodes: &[u8]) -> Result<String, ObjectIdentifierError> {
|
|||||||
Ok(out)
|
Ok(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<String> for &ObjectIdentifier {
|
impl Into<String> for &ObjectIdentifier<'_> {
|
||||||
fn into(self) -> String {
|
fn into(self) -> String {
|
||||||
convert_to_string(&self.nodes).expect("Valid OID object couldn't be serialized.")
|
convert_to_string(&self.nodes).expect("Valid OID object couldn't be serialized.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<String> for ObjectIdentifier {
|
impl Into<String> for ObjectIdentifier <'_>{
|
||||||
fn into(self) -> String {
|
fn into(self) -> String {
|
||||||
(&self).into()
|
(&self).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Into<&'a [u8]> for &'a ObjectIdentifier {
|
impl<'a> Into<&'a [u8]> for &'a ObjectIdentifier<'_> {
|
||||||
fn into(self) -> &'a [u8] {
|
fn into(self) -> &'a [u8] {
|
||||||
&self.nodes
|
&self.nodes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<Vec<u8>> for ObjectIdentifier {
|
impl Into<Vec<u8>> for ObjectIdentifier<'_> {
|
||||||
fn into(self) -> Vec<u8> {
|
fn into(self) -> Vec<u8> {
|
||||||
self.nodes.into_vec()
|
self.nodes.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&str> for ObjectIdentifier {
|
impl TryFrom<&str> for ObjectIdentifier<'static> {
|
||||||
type Error = ObjectIdentifierError;
|
type Error = ObjectIdentifierError;
|
||||||
fn try_from(value: &str) -> Result<ObjectIdentifier, Self::Error> {
|
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||||
ObjectIdentifier::from_string(value)
|
ObjectIdentifier::from_string(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<String> for ObjectIdentifier {
|
impl TryFrom<String> for ObjectIdentifier<'static> {
|
||||||
type Error = ObjectIdentifierError;
|
type Error = ObjectIdentifierError;
|
||||||
fn try_from(value: String) -> Result<ObjectIdentifier, Self::Error> {
|
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||||
ObjectIdentifier::from_string(value)
|
ObjectIdentifier::from_string(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&[u8]> for ObjectIdentifier {
|
impl<'a> TryFrom<&'a [u8]> for ObjectIdentifier<'a> {
|
||||||
type Error = ObjectIdentifierError;
|
type Error = ObjectIdentifierError;
|
||||||
fn try_from(nodes: &[u8]) -> Result<ObjectIdentifier, Self::Error> {
|
fn try_from(nodes: &'a [u8]) -> Result<Self, Self::Error> {
|
||||||
Self::from_box(nodes.into())
|
Self::from_box(Cow::Borrowed(nodes))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<Vec<u8>> for ObjectIdentifier {
|
impl TryFrom<Vec<u8>> for ObjectIdentifier<'static> {
|
||||||
type Error = ObjectIdentifierError;
|
type Error = ObjectIdentifierError;
|
||||||
fn try_from(value: Vec<u8>) -> Result<ObjectIdentifier, Self::Error> {
|
fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
|
||||||
Self::from_box(value.into_boxed_slice())
|
Self::from_box(Cow::from(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -410,17 +412,17 @@ mod serde_support {
|
|||||||
struct OidVisitor;
|
struct OidVisitor;
|
||||||
|
|
||||||
impl<'de> de::Visitor<'de> for OidVisitor {
|
impl<'de> de::Visitor<'de> for OidVisitor {
|
||||||
type Value = ObjectIdentifier;
|
type Value = ObjectIdentifier<'de>;
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
formatter.write_str("a valid buffer representing an OID")
|
formatter.write_str("a valid buffer representing an OID")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: de::Error,
|
E: de::Error,
|
||||||
{
|
{
|
||||||
ObjectIdentifier::try_from(v).map_err(|err| {
|
ObjectIdentifier::try_from(v).map_err(move |err| {
|
||||||
E::invalid_value(
|
E::invalid_value(
|
||||||
de::Unexpected::Other(match err {
|
de::Unexpected::Other(match err {
|
||||||
ObjectIdentifierError::IllegalRootNode => "illegal root node",
|
ObjectIdentifierError::IllegalRootNode => "illegal root node",
|
||||||
@ -449,8 +451,8 @@ mod serde_support {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de> de::Deserialize<'de> for ObjectIdentifier {
|
impl<'de> de::Deserialize<'de> for ObjectIdentifier<'de> {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<ObjectIdentifier, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<ObjectIdentifier<'de>, D::Error>
|
||||||
where
|
where
|
||||||
D: de::Deserializer<'de>,
|
D: de::Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@ -462,7 +464,7 @@ mod serde_support {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ser::Serialize for ObjectIdentifier {
|
impl ser::Serialize for ObjectIdentifier<'_> {
|
||||||
fn serialize<S>(
|
fn serialize<S>(
|
||||||
&self,
|
&self,
|
||||||
serializer: S,
|
serializer: S,
|
||||||
@ -494,6 +496,67 @@ mod serde_support {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper macro to declare Object Identifiers at compile-time
|
||||||
|
///
|
||||||
|
/// Since the DER encoded oids are not very readable we provide a
|
||||||
|
/// procedural macro `oid!`. The macro can be used the following ways:
|
||||||
|
///
|
||||||
|
/// - `oid!(1.4.42.23)`: Create a const expression for the corresponding `Oid<'static>`
|
||||||
|
/// - `oid!(rel 42.23)`: Create a const expression for the corresponding relative `Oid<'static>`
|
||||||
|
/// - `oid!(raw 1.4.42.23)`/`oid!(raw rel 42.23)`: Obtain the DER encoded form as a byte array.
|
||||||
|
///
|
||||||
|
/// # Comparing oids
|
||||||
|
///
|
||||||
|
/// Comparing a parsed oid to a static oid is probably the most common
|
||||||
|
/// thing done with oids in your code. The `oid!` macro can be used in expression positions for
|
||||||
|
/// this purpose. For example
|
||||||
|
/// ```
|
||||||
|
/// use diflouroborane::oid;
|
||||||
|
/// use diflouroborane::utils::oid::ObjectIdentifier;
|
||||||
|
///
|
||||||
|
/// # let some_oid: ObjectIdentifier = oid!(1.2.456);
|
||||||
|
/// const SOME_STATIC_OID: ObjectIdentifier = oid!(1.2.456);
|
||||||
|
/// assert_eq!(some_oid, SOME_STATIC_OID)
|
||||||
|
/// ```
|
||||||
|
/// To get a relative Oid use `oid!(rel 1.2)`.
|
||||||
|
///
|
||||||
|
/// Because of limitations for procedural macros ([rust issue](https://github.com/rust-lang/rust/issues/54727))
|
||||||
|
/// and constants used in patterns ([rust issue](https://github.com/rust-lang/rust/issues/31434))
|
||||||
|
/// the `oid` macro can not directly be used in patterns, also not through constants.
|
||||||
|
/// You can do this, though:
|
||||||
|
/// ```
|
||||||
|
/// # use diflouroborane::oid;
|
||||||
|
/// # use diflouroborane::utils::oid::ObjectIdentifier;
|
||||||
|
/// # let some_oid: ObjectIdentifier<'static> = oid!(1.2.456);
|
||||||
|
/// const SOME_OID: ObjectIdentifier<'static> = oid!(1.2.456);
|
||||||
|
/// if some_oid == SOME_OID || some_oid == oid!(1.2.456) {
|
||||||
|
/// println!("match");
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// // Alternatively, compare the DER encoded form directly:
|
||||||
|
/// const SOME_OID_RAW: &[u8] = &oid!(raw 1.2.456);
|
||||||
|
/// match some_oid.as_bytes() {
|
||||||
|
/// SOME_OID_RAW => println!("match"),
|
||||||
|
/// _ => panic!("no match"),
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
/// *Attention*, be aware that the latter version might not handle the case of a relative oid correctly. An
|
||||||
|
/// extra check might be necessary.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! oid {
|
||||||
|
(raw $( $item:literal ).*) => {
|
||||||
|
::bffh_impl::encode_oid!( $( $item ).* )
|
||||||
|
};
|
||||||
|
(raw $items:expr) => {
|
||||||
|
::bffh_impl::encode_oid!($items)
|
||||||
|
};
|
||||||
|
($($item:literal ).*) => {
|
||||||
|
$crate::utils::oid::ObjectIdentifier::new_unchecked(::std::borrow::Cow::Borrowed(
|
||||||
|
&$crate::oid!(raw $( $item ).*),
|
||||||
|
))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) mod tests {
|
pub(crate) mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
Loading…
Reference in New Issue
Block a user