netdoc: parse multiple authcerts from a string.

This commit is contained in:
Nick Mathewson 2020-08-26 15:41:46 -04:00
parent 696e7ad334
commit 86f6f30b6d
2 changed files with 42 additions and 0 deletions

View File

@ -82,6 +82,11 @@ impl AuthCert {
result
}
/// Return an iterator yielding authority certificates from a string.
pub fn parse_multiple(s: &str) -> impl Iterator<Item = Result<AuthCert>> + '_ {
AuthCertIterator(NetDocReader::new(s))
}
/// Return true if this certificate is expired at a given time, or
/// not yet valid at that time.
pub fn is_expired_at(&self, when: time::SystemTime) -> bool {
@ -202,6 +207,38 @@ impl AuthCert {
expires,
})
}
/// Skip tokens from the reader until the next token (if any) is
/// the start of cert.
fn advance_reader_to_next(reader: &mut NetDocReader<'_, AuthCertKW>) {
use AuthCertKW::*;
let iter = reader.iter();
while let Some(Ok(item)) = iter.peek() {
if item.get_kwd() == DIR_KEY_CERTIFICATE_VERSION {
return;
}
iter.next();
}
}
}
struct AuthCertIterator<'a>(NetDocReader<'a, AuthCertKW>);
impl<'a> Iterator for AuthCertIterator<'a> {
type Item = Result<AuthCert>;
fn next(&mut self) -> Option<Result<AuthCert>> {
if self.0.is_exhausted() {
return None;
}
let result = AuthCert::take_from_reader(&mut self.0);
if result.is_err() {
// XXXX Verify that at least one item was consumed from the
// XXXX reader!
AuthCert::advance_reader_to_next(&mut self.0);
}
Some(result.map_err(|e| e.within(self.0.str())))
}
}
#[cfg(test)]

View File

@ -582,6 +582,11 @@ impl<'a, K: Keyword> NetDocReader<'a, K> {
self.pause_at(|_| false)
}
/// Return true if there are no more items in this NetDocReader.
pub fn is_exhausted(&mut self) -> bool {
self.iter().peek().is_none()
}
/// Give an error if there are remaining tokens in this NetDocReader.
pub fn should_be_exhausted(&mut self) -> Result<()> {
match self.iter().peek() {