gix_actor/signature/
mod.rs1mod _ref {
2 use bstr::ByteSlice;
3
4 use crate::{signature::decode, IdentityRef, Signature, SignatureRef};
5
6 impl<'a> SignatureRef<'a> {
8 pub fn from_bytes(mut data: &'a [u8]) -> Result<SignatureRef<'a>, gix_error::ValidationError> {
12 Self::from_bytes_consuming(&mut data)
13 }
14
15 pub fn from_bytes_consuming(data: &mut &'a [u8]) -> Result<SignatureRef<'a>, gix_error::ValidationError> {
21 decode(data)
22 }
23
24 pub fn to_owned(&self) -> Result<Signature, gix_date::Error> {
26 Ok(Signature {
27 name: self.name.to_owned(),
28 email: self.email.to_owned(),
29 time: self.time()?,
30 })
31 }
32 }
33
34 impl<'a> SignatureRef<'a> {
36 pub fn trim(&self) -> SignatureRef<'a> {
38 SignatureRef {
39 name: self.name.trim().as_bstr(),
40 email: self.email.trim().as_bstr(),
41 time: self.time.trim(),
42 }
43 }
44
45 pub fn actor(&self) -> IdentityRef<'a> {
47 IdentityRef {
48 name: self.name,
49 email: self.email,
50 }
51 }
52
53 pub fn seconds(&self) -> gix_date::SecondsSinceUnixEpoch {
58 self.time
59 .trim()
60 .split(' ')
61 .next()
62 .and_then(|i| i.parse().ok())
63 .unwrap_or_default()
64 }
65
66 pub fn time(&self) -> Result<gix_date::Time, gix_date::Error> {
69 self.time.parse()
70 }
71 }
72}
73
74mod convert {
75 use gix_date::parse::TimeBuf;
76
77 use crate::{Signature, SignatureRef};
78
79 impl Signature {
80 pub fn to_ref<'a>(&'a self, time_buf: &'a mut TimeBuf) -> SignatureRef<'a> {
84 SignatureRef {
85 name: self.name.as_ref(),
86 email: self.email.as_ref(),
87 time: self.time.to_str(time_buf),
88 }
89 }
90 }
91
92 impl From<SignatureRef<'_>> for Signature {
94 fn from(other: SignatureRef<'_>) -> Signature {
95 Signature {
96 name: other.name.to_owned(),
97 email: other.email.to_owned(),
98 time: other.time().unwrap_or_default(),
99 }
100 }
101 }
102}
103
104pub(crate) mod write {
105 use bstr::{BStr, ByteSlice};
106 use gix_date::parse::TimeBuf;
107
108 use crate::{Signature, SignatureRef};
109
110 impl Signature {
112 pub fn write_to(&self, out: &mut dyn std::io::Write) -> std::io::Result<()> {
114 let mut buf = TimeBuf::default();
115 self.to_ref(&mut buf).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 impl SignatureRef<'_> {
124 pub fn write_to(&self, out: &mut dyn std::io::Write) -> std::io::Result<()> {
126 out.write_all(validated_token(self.name).map_err(std::io::Error::other)?)?;
127 out.write_all(b" ")?;
128 out.write_all(b"<")?;
129 out.write_all(validated_token(self.email).map_err(std::io::Error::other)?)?;
130 out.write_all(b"> ")?;
131 out.write_all(validated_token(self.time.into()).map_err(std::io::Error::other)?)
132 }
133 pub fn size(&self) -> usize {
135 self.name.len() + 2 + self.email.len() + 2 + self.time.len()
136 }
137 }
138
139 pub(crate) fn validated_token(name: &BStr) -> Result<&BStr, gix_error::ValidationError> {
140 if name.find_byteset(b"<>\n").is_some() {
141 return Err(gix_error::ValidationError::new_with_input(
142 "Signature name or email must not contain '<', '>' or \\n",
143 name,
144 ));
145 }
146 Ok(name)
147 }
148}
149
150pub mod decode;
152pub use decode::function::decode;