gix_actor/signature/
mod.rs1mod _ref {
2 use bstr::ByteSlice;
3 use winnow::{error::StrContext, prelude::*};
4
5 use crate::{signature::decode, IdentityRef, Signature, SignatureRef};
6
7 impl<'a> SignatureRef<'a> {
8 pub fn from_bytes<E>(mut data: &'a [u8]) -> Result<SignatureRef<'a>, winnow::error::ErrMode<E>>
10 where
11 E: winnow::error::ParserError<&'a [u8]> + winnow::error::AddContext<&'a [u8], StrContext>,
12 {
13 decode.parse_next(&mut data)
14 }
15
16 pub fn to_owned(&self) -> Signature {
18 Signature {
19 name: self.name.to_owned(),
20 email: self.email.to_owned(),
21 time: self.time,
22 }
23 }
24
25 pub fn trim(&self) -> SignatureRef<'a> {
27 SignatureRef {
28 name: self.name.trim().as_bstr(),
29 email: self.email.trim().as_bstr(),
30 time: self.time,
31 }
32 }
33
34 pub fn actor(&self) -> IdentityRef<'a> {
36 IdentityRef {
37 name: self.name,
38 email: self.email,
39 }
40 }
41 }
42}
43
44mod convert {
45 use crate::{Signature, SignatureRef};
46
47 impl Signature {
48 pub fn to_ref(&self) -> SignatureRef<'_> {
50 SignatureRef {
51 name: self.name.as_ref(),
52 email: self.email.as_ref(),
53 time: self.time,
54 }
55 }
56 }
57
58 impl From<SignatureRef<'_>> for Signature {
59 fn from(other: SignatureRef<'_>) -> Signature {
60 let SignatureRef { name, email, time } = other;
61 Signature {
62 name: name.to_owned(),
63 email: email.to_owned(),
64 time,
65 }
66 }
67 }
68
69 impl<'a> From<&'a Signature> for SignatureRef<'a> {
70 fn from(other: &'a Signature) -> SignatureRef<'a> {
71 other.to_ref()
72 }
73 }
74}
75
76pub(crate) mod write {
77 use bstr::{BStr, ByteSlice};
78
79 use crate::{Signature, SignatureRef};
80
81 #[derive(Debug, thiserror::Error)]
83 #[allow(missing_docs)]
84 pub(crate) enum Error {
85 #[error("Signature name or email must not contain '<', '>' or \\n")]
86 IllegalCharacter,
87 }
88
89 impl From<Error> for std::io::Error {
90 fn from(err: Error) -> Self {
91 std::io::Error::new(std::io::ErrorKind::Other, err)
92 }
93 }
94
95 impl Signature {
97 pub fn write_to(&self, out: &mut dyn std::io::Write) -> std::io::Result<()> {
99 self.to_ref().write_to(out)
100 }
101 pub fn size(&self) -> usize {
103 self.to_ref().size()
104 }
105 }
106
107 impl SignatureRef<'_> {
108 pub fn write_to(&self, out: &mut dyn std::io::Write) -> std::io::Result<()> {
110 out.write_all(validated_token(self.name)?)?;
111 out.write_all(b" ")?;
112 out.write_all(b"<")?;
113 out.write_all(validated_token(self.email)?)?;
114 out.write_all(b"> ")?;
115 self.time.write_to(out)
116 }
117 pub fn size(&self) -> usize {
119 self.name.len() + 2 + self.email.len() + 2 + self.time.size()
120 }
121 }
122
123 pub(crate) fn validated_token(name: &BStr) -> Result<&BStr, Error> {
124 if name.find_byteset(b"<>\n").is_some() {
125 return Err(Error::IllegalCharacter);
126 }
127 Ok(name)
128 }
129}
130
131pub mod decode;
133pub use decode::function::decode;