radicle-cob: simplify trailers module

The macro in the trailers module existed since there were multiple
trailers before the refactoring, so it minimised boilerplate code.

After the refactoring of the code there was only one trailer
left. Remove the macro generation code and replace it with just the
necessary code for the ResourceCommitTrailer.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
This commit is contained in:
Fintan Halpenny 2023-02-13 11:13:47 +00:00 committed by Alexis Sellier
parent 602299734a
commit 99c1e2ac52
No known key found for this signature in database
1 changed files with 70 additions and 99 deletions

View File

@ -3,108 +3,79 @@
// This file is part of radicle-link, distributed under the GPLv3 with Radicle // This file is part of radicle-link, distributed under the GPLv3 with Radicle
// Linking Exception. For full terms see the included LICENSE file. // Linking Exception. For full terms see the included LICENSE file.
mod resource_identity { use git_trailers::{OwnedTrailer, Token, Trailer};
super::oid_trailer! {ResourceCommitTrailer, "Rad-Resource"} use radicle_git_ext as ext;
}
pub mod error { pub mod error {
pub use super::resource_identity::Error as InvalidResourceTrailer; use thiserror::Error;
}
pub use resource_identity::ResourceCommitTrailer; #[derive(Debug, Error)]
pub enum InvalidResourceTrailer {
/// A macro for generating boilerplate From and TryFrom impls for trailers which #[error("found wrong token for Rad-Resource tailer")]
/// have git object IDs as their values
#[macro_export]
macro_rules! oid_trailer {
($typename:ident, $trailer:literal) => {
use git_trailers::{OwnedTrailer, Token, Trailer};
use radicle_git_ext as ext;
use std::convert::{TryFrom, TryInto};
#[derive(Debug)]
pub enum Error {
WrongToken, WrongToken,
#[error("no Rad-Resource")]
NoTrailer, NoTrailer,
#[error("no value for Rad-Resource")]
NoValue, NoValue,
#[error("invalid git OID")]
InvalidOid, InvalidOid,
} }
}
// We can't use `derive(thiserror::Error)` as we need to concat strings with pub struct ResourceCommitTrailer(git2::Oid);
// $trailer and macros are not allowed in non-key-value attributes
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::WrongToken => {
write!(f, concat!("found wrong token for ", $trailer, " trailer"))
}
Self::NoTrailer => write!(f, concat!("no ", $trailer)),
Self::NoValue => write!(f, concat!("no value for ", $trailer, " trailer")),
Self::InvalidOid => write!(f, "invalid git OID"),
}
}
}
impl std::error::Error for Error {} impl ResourceCommitTrailer {
pub struct $typename(git2::Oid);
impl $typename {
pub fn oid(&self) -> git2::Oid { pub fn oid(&self) -> git2::Oid {
self.0 self.0
} }
} }
impl From<git2::Oid> for $typename { impl TryFrom<&Trailer<'_>> for ResourceCommitTrailer {
type Error = error::InvalidResourceTrailer;
fn try_from(Trailer { values, token }: &Trailer<'_>) -> Result<Self, Self::Error> {
let val = values.first().ok_or(Self::Error::NoValue)?;
let ext_oid =
radicle_git_ext::Oid::try_from(val.as_ref()).map_err(|_| Self::Error::InvalidOid)?;
if Some(token) == Token::try_from("Rad-Resource").ok().as_ref() {
Ok(ResourceCommitTrailer(ext_oid.into()))
} else {
Err(Self::Error::WrongToken)
}
}
}
impl TryFrom<&OwnedTrailer> for ResourceCommitTrailer {
type Error = error::InvalidResourceTrailer;
fn try_from(trailer: &OwnedTrailer) -> Result<Self, Self::Error> {
Self::try_from(&Trailer::from(trailer))
}
}
impl From<git2::Oid> for ResourceCommitTrailer {
fn from(oid: git2::Oid) -> Self { fn from(oid: git2::Oid) -> Self {
$typename(oid) Self(oid)
}
} }
}
impl From<$typename> for Trailer<'_> { impl From<ResourceCommitTrailer> for Trailer<'_> {
fn from(containing: $typename) -> Self { fn from(containing: ResourceCommitTrailer) -> Self {
Trailer { Trailer {
token: Token::try_from($trailer).unwrap(), token: Token::try_from("Rad-Resource").unwrap(),
values: vec![containing.0.to_string().into()], values: vec![containing.0.to_string().into()],
} }
} }
} }
impl From<$typename> for OwnedTrailer { impl From<ResourceCommitTrailer> for OwnedTrailer {
fn from(containing: $typename) -> Self { fn from(containing: ResourceCommitTrailer) -> Self {
Trailer::from(containing).to_owned() Trailer::from(containing).to_owned()
} }
}
impl TryFrom<&Trailer<'_>> for $typename {
type Error = Error;
fn try_from(Trailer { values, token }: &Trailer<'_>) -> Result<Self, Self::Error> {
let val = values.first().ok_or(Error::NoValue)?;
let ext_oid =
radicle_git_ext::Oid::try_from(val.as_ref()).map_err(|_| Error::InvalidOid)?;
if Some(token) == Token::try_from($trailer).ok().as_ref() {
Ok($typename(ext_oid.into()))
} else {
Err(Error::WrongToken)
}
}
}
impl TryFrom<&OwnedTrailer> for $typename {
type Error = Error;
fn try_from(trailer: &OwnedTrailer) -> Result<Self, Self::Error> {
(&Trailer::from(trailer)).try_into()
}
}
impl From<ext::Oid> for $typename {
fn from(oid: ext::Oid) -> Self {
$typename(oid.into())
}
}
};
} }
pub(crate) use oid_trailer;
impl From<ext::Oid> for ResourceCommitTrailer {
fn from(oid: ext::Oid) -> Self {
Self(oid.into())
}
}