diff options
Diffstat (limited to 'vendor/gix-actor/src')
-rw-r--r-- | vendor/gix-actor/src/identity.rs | 82 | ||||
-rw-r--r-- | vendor/gix-actor/src/lib.rs | 26 | ||||
-rw-r--r-- | vendor/gix-actor/src/signature/decode.rs | 154 | ||||
-rw-r--r-- | vendor/gix-actor/src/signature/mod.rs | 36 |
4 files changed, 211 insertions, 87 deletions
diff --git a/vendor/gix-actor/src/identity.rs b/vendor/gix-actor/src/identity.rs new file mode 100644 index 000000000..0e7c0e6d5 --- /dev/null +++ b/vendor/gix-actor/src/identity.rs @@ -0,0 +1,82 @@ +use bstr::ByteSlice; + +use crate::{signature::decode, Identity, IdentityRef}; + +impl<'a> IdentityRef<'a> { + /// Deserialize an identity from the given `data`. + pub fn from_bytes<E>(data: &'a [u8]) -> Result<Self, nom::Err<E>> + where + E: nom::error::ParseError<&'a [u8]> + nom::error::ContextError<&'a [u8]>, + { + decode::identity(data).map(|(_, t)| t) + } + + /// Create an owned instance from this shared one. + pub fn to_owned(&self) -> Identity { + Identity { + name: self.name.to_owned(), + email: self.email.to_owned(), + } + } + + /// Trim whitespace surrounding the name and email and return a new identity. + pub fn trim(&self) -> IdentityRef<'a> { + IdentityRef { + name: self.name.trim().as_bstr(), + email: self.email.trim().as_bstr(), + } + } +} + +mod write { + use crate::{signature::write::validated_token, Identity, IdentityRef}; + + /// Output + impl Identity { + /// Serialize this instance to `out` in the git serialization format for signatures (but without timestamp). + pub fn write_to(&self, out: impl std::io::Write) -> std::io::Result<()> { + self.to_ref().write_to(out) + } + } + + impl<'a> IdentityRef<'a> { + /// Serialize this instance to `out` in the git serialization format for signatures (but without timestamp). + pub fn write_to(&self, mut out: impl std::io::Write) -> std::io::Result<()> { + out.write_all(validated_token(self.name)?)?; + out.write_all(b" ")?; + out.write_all(b"<")?; + out.write_all(validated_token(self.email)?)?; + out.write_all(b">") + } + } +} + +mod impls { + use crate::{Identity, IdentityRef}; + + impl Identity { + /// Borrow this instance as immutable + pub fn to_ref(&self) -> IdentityRef<'_> { + IdentityRef { + name: self.name.as_ref(), + email: self.email.as_ref(), + } + } + } + + impl From<IdentityRef<'_>> for Identity { + fn from(other: IdentityRef<'_>) -> Identity { + let IdentityRef { name, email } = other; + Identity { + name: name.to_owned(), + email: email.to_owned(), + } + } + } + + impl<'a> From<&'a Identity> for IdentityRef<'a> { + fn from(other: &'a Identity) -> IdentityRef<'a> { + other.to_ref() + } + } +} diff --git a/vendor/gix-actor/src/lib.rs b/vendor/gix-actor/src/lib.rs index 336d4f79f..93d8bdb0f 100644 --- a/vendor/gix-actor/src/lib.rs +++ b/vendor/gix-actor/src/lib.rs @@ -1,4 +1,4 @@ -//! This crate provides ways of identifying an actor within the git repository both in shared/mutable and mutable variants. +//! This crate provides ways of identifying an actor within the git repository both in shared and mutable variants. //! //! ## Feature Flags #![cfg_attr( @@ -12,9 +12,31 @@ use bstr::{BStr, BString}; pub use gix_date::{time::Sign, Time}; +mod identity; /// pub mod signature; +/// A person with name and email. +#[derive(Default, PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct Identity { + /// The actors name. + pub name: BString, + /// The actor's email. + pub email: BString, +} + +/// A person with name and email, as reference. +#[derive(Default, PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct IdentityRef<'a> { + /// The actors name. + #[cfg_attr(feature = "serde", serde(borrow))] + pub name: &'a BStr, + /// The actor's email. + pub email: &'a BStr, +} + /// A mutable signature is created by an actor at a certain time. /// /// Note that this is not a cryptographical signature. @@ -32,7 +54,7 @@ pub struct Signature { /// A immutable signature is created by an actor at a certain time. /// /// Note that this is not a cryptographical signature. -#[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy, Default)] +#[derive(Default, PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct SignatureRef<'a> { /// The actor's name. diff --git a/vendor/gix-actor/src/signature/decode.rs b/vendor/gix-actor/src/signature/decode.rs index 5483d1651..6bd7bfed6 100644 --- a/vendor/gix-actor/src/signature/decode.rs +++ b/vendor/gix-actor/src/signature/decode.rs @@ -1,69 +1,93 @@ -use bstr::ByteSlice; -use btoi::btoi; -use nom::{ - branch::alt, - bytes::complete::{tag, take, take_until, take_while_m_n}, - character::is_digit, - error::{context, ContextError, ParseError}, - sequence::{terminated, tuple}, - IResult, -}; - -use crate::{Sign, SignatureRef, Time}; - -const SPACE: &[u8] = b" "; - -/// Parse a signature from the bytes input `i` using `nom`. -pub fn decode<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>( - i: &'a [u8], -) -> IResult<&'a [u8], SignatureRef<'a>, E> { - let (i, (name, email, time, tzsign, hours, minutes)) = context( - "<name> <<email>> <timestamp> <+|-><HHMM>", - tuple(( - context("<name>", terminated(take_until(&b" <"[..]), take(2usize))), - context("<email>", terminated(take_until(&b"> "[..]), take(2usize))), - context("<timestamp>", |i| { - terminated(take_until(SPACE), take(1usize))(i).and_then(|(i, v)| { - btoi::<u32>(v) - .map(|v| (i, v)) - .map_err(|_| nom::Err::Error(E::from_error_kind(i, nom::error::ErrorKind::MapRes))) - }) - }), - context("+|-", alt((tag(b"-"), tag(b"+")))), - context("HH", |i| { - take_while_m_n(2usize, 2, is_digit)(i).and_then(|(i, v)| { - btoi::<i32>(v) - .map(|v| (i, v)) - .map_err(|_| nom::Err::Error(E::from_error_kind(i, nom::error::ErrorKind::MapRes))) - }) - }), - context("MM", |i| { - take_while_m_n(2usize, 2, is_digit)(i).and_then(|(i, v)| { - btoi::<i32>(v) - .map(|v| (i, v)) - .map_err(|_| nom::Err::Error(E::from_error_kind(i, nom::error::ErrorKind::MapRes))) - }) - }), - )), - )(i)?; - - debug_assert!(tzsign[0] == b'-' || tzsign[0] == b'+', "parser assure it's +|- only"); - let sign = if tzsign[0] == b'-' { Sign::Minus } else { Sign::Plus }; // - let offset = (hours * 3600 + minutes * 60) * if sign == Sign::Minus { -1 } else { 1 }; - - Ok(( - i, - SignatureRef { - name: name.as_bstr(), - email: email.as_bstr(), - time: Time { - seconds_since_unix_epoch: time, - offset_in_seconds: offset, - sign, +pub(crate) mod function { + use bstr::ByteSlice; + use btoi::btoi; + use nom::{ + branch::alt, + bytes::complete::{tag, take, take_until, take_while_m_n}, + character::is_digit, + error::{context, ContextError, ParseError}, + sequence::{terminated, tuple}, + IResult, + }; + + use crate::{IdentityRef, Sign, SignatureRef, Time}; + + const SPACE: &[u8] = b" "; + + /// Parse a signature from the bytes input `i` using `nom`. + pub fn decode<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>( + i: &'a [u8], + ) -> IResult<&'a [u8], SignatureRef<'a>, E> { + let (i, (identity, _, time, tzsign, hours, minutes)) = context( + "<name> <<email>> <timestamp> <+|-><HHMM>", + tuple(( + identity, + tag(b" "), + context("<timestamp>", |i| { + terminated(take_until(SPACE), take(1usize))(i).and_then(|(i, v)| { + btoi::<u32>(v) + .map(|v| (i, v)) + .map_err(|_| nom::Err::Error(E::from_error_kind(i, nom::error::ErrorKind::MapRes))) + }) + }), + context("+|-", alt((tag(b"-"), tag(b"+")))), + context("HH", |i| { + take_while_m_n(2usize, 2, is_digit)(i).and_then(|(i, v)| { + btoi::<i32>(v) + .map(|v| (i, v)) + .map_err(|_| nom::Err::Error(E::from_error_kind(i, nom::error::ErrorKind::MapRes))) + }) + }), + context("MM", |i| { + take_while_m_n(2usize, 2, is_digit)(i).and_then(|(i, v)| { + btoi::<i32>(v) + .map(|v| (i, v)) + .map_err(|_| nom::Err::Error(E::from_error_kind(i, nom::error::ErrorKind::MapRes))) + }) + }), + )), + )(i)?; + + debug_assert!(tzsign[0] == b'-' || tzsign[0] == b'+', "parser assure it's +|- only"); + let sign = if tzsign[0] == b'-' { Sign::Minus } else { Sign::Plus }; // + let offset = (hours * 3600 + minutes * 60) * if sign == Sign::Minus { -1 } else { 1 }; + + Ok(( + i, + SignatureRef { + name: identity.name, + email: identity.email, + time: Time { + seconds_since_unix_epoch: time, + offset_in_seconds: offset, + sign, + }, + }, + )) + } + + /// Parse an identity from the bytes input `i` (like `name <email>`) using `nom`. + pub fn identity<'a, E: ParseError<&'a [u8]> + ContextError<&'a [u8]>>( + i: &'a [u8], + ) -> IResult<&'a [u8], IdentityRef<'a>, E> { + let (i, (name, email)) = context( + "<name> <<email>>", + tuple(( + context("<name>", terminated(take_until(&b" <"[..]), take(2usize))), + context("<email>", terminated(take_until(&b">"[..]), take(1usize))), + )), + )(i)?; + + Ok(( + i, + IdentityRef { + name: name.as_bstr(), + email: email.as_bstr(), }, - }, - )) + )) + } } +pub use function::identity; #[cfg(test)] mod tests { @@ -141,7 +165,7 @@ mod tests { .map_err(to_bstr_err) .expect_err("parse fails as > is missing") .to_string(), - "Parse error:\nTakeUntil at: 12345 -1215\nin section '<email>', at: 12345 -1215\nin section '<name> <<email>> <timestamp> <+|-><HHMM>', at: hello < 12345 -1215\n" + "Parse error:\nTakeUntil at: 12345 -1215\nin section '<email>', at: 12345 -1215\nin section '<name> <<email>>', at: hello < 12345 -1215\nin section '<name> <<email>> <timestamp> <+|-><HHMM>', at: hello < 12345 -1215\n" ); } diff --git a/vendor/gix-actor/src/signature/mod.rs b/vendor/gix-actor/src/signature/mod.rs index fa5fb8470..8634ba595 100644 --- a/vendor/gix-actor/src/signature/mod.rs +++ b/vendor/gix-actor/src/signature/mod.rs @@ -1,7 +1,7 @@ mod _ref { - use bstr::{BStr, ByteSlice}; + use bstr::ByteSlice; - use crate::{signature::decode, Signature, SignatureRef}; + use crate::{signature::decode, IdentityRef, Signature, SignatureRef}; impl<'a> SignatureRef<'a> { /// Deserialize a signature from the given `data`. @@ -31,8 +31,11 @@ mod _ref { } /// Return the actor's name and email, effectively excluding the time stamp of this signature. - pub fn actor(&self) -> (&BStr, &BStr) { - (self.name, self.email) + pub fn actor(&self) -> IdentityRef<'a> { + IdentityRef { + name: self.name, + email: self.email, + } } } } @@ -41,11 +44,6 @@ mod convert { use crate::{Signature, SignatureRef}; impl Signature { - /// An empty signature, similar to 'null'. - pub fn empty() -> Self { - Signature::default() - } - /// Borrow this instance as immutable pub fn to_ref(&self) -> SignatureRef<'_> { SignatureRef { @@ -74,9 +72,7 @@ mod convert { } } -mod write { - use std::io; - +pub(crate) mod write { use bstr::{BStr, ByteSlice}; use crate::{Signature, SignatureRef}; @@ -84,21 +80,21 @@ mod write { /// The Error produced by [`Signature::write_to()`]. #[derive(Debug, thiserror::Error)] #[allow(missing_docs)] - enum Error { + pub(crate) enum Error { #[error("Signature name or email must not contain '<', '>' or \\n")] IllegalCharacter, } - impl From<Error> for io::Error { + impl From<Error> for std::io::Error { fn from(err: Error) -> Self { - io::Error::new(io::ErrorKind::Other, err) + std::io::Error::new(std::io::ErrorKind::Other, err) } } /// Output impl Signature { /// Serialize this instance to `out` in the git serialization format for actors. - pub fn write_to(&self, out: impl io::Write) -> io::Result<()> { + pub fn write_to(&self, out: impl std::io::Write) -> std::io::Result<()> { self.to_ref().write_to(out) } /// Computes the number of bytes necessary to serialize this signature @@ -109,7 +105,7 @@ mod write { impl<'a> SignatureRef<'a> { /// Serialize this instance to `out` in the git serialization format for actors. - pub fn write_to(&self, mut out: impl io::Write) -> io::Result<()> { + pub fn write_to(&self, mut out: impl std::io::Write) -> std::io::Result<()> { out.write_all(validated_token(self.name)?)?; out.write_all(b" ")?; out.write_all(b"<")?; @@ -123,7 +119,7 @@ mod write { } } - fn validated_token(name: &BStr) -> Result<&BStr, Error> { + pub(crate) fn validated_token(name: &BStr) -> Result<&BStr, Error> { if name.find_byteset(b"<>\n").is_some() { return Err(Error::IllegalCharacter); } @@ -132,5 +128,5 @@ mod write { } /// -mod decode; -pub use decode::decode; +pub mod decode; +pub use decode::function::decode; |