Remove intermediate lifetime.

This commit is contained in:
Tom Alexander
2023-10-29 14:14:10 -04:00
parent 6109902945
commit 645ae26701
60 changed files with 266 additions and 249 deletions

View File

@@ -1,5 +1,7 @@
use std::collections::HashMap;
use super::ast_node::IntoIAstNode;
use crate::error::CustomError;
use organic::types::Element;
use organic::types::Object;
@@ -7,14 +9,14 @@ use super::ast_node::IAstNode;
type IdCounter = u16;
pub(crate) struct Registry<'intermediate, 'parse> {
pub(crate) struct Registry<'parse> {
id_counter: IdCounter,
targets: HashMap<&'parse str, String>,
footnote_ids: Vec<(Option<&'parse str>, Vec<IAstNode>)>,
}
impl<'intermediate, 'parse> Registry<'intermediate, 'parse> {
pub(crate) fn new() -> Registry<'intermediate, 'parse> {
impl<'parse> Registry<'parse> {
pub(crate) fn new() -> Registry<'parse> {
Registry {
id_counter: 0,
targets: HashMap::new(),
@@ -32,16 +34,16 @@ impl<'intermediate, 'parse> Registry<'intermediate, 'parse> {
/// Get a 0-indexed ID for a footnote.
///
/// This needs to be incremented to be 1-indexed for render.
pub(crate) fn get_footnote_reference_id<'b>(
pub(crate) async fn get_footnote_reference_id<'b>(
&'b mut self,
label: Option<&'parse str>,
definition: &'intermediate Vec<Object<'parse>>,
) -> usize {
definition: &'b Vec<Object<'parse>>,
) -> Result<usize, CustomError> {
if let None = label {
// If it has no label then it must always get a new ID.
self.footnote_ids
.push((None, FootnoteDefinitionContents::FromReference(definition)));
return self.footnote_ids.len() - 1;
let contents = convert_reference_contents(self, definition).await?;
self.footnote_ids.push((None, contents));
return Ok(self.footnote_ids.len() - 1);
}
if let Some(existing_id) = self
@@ -50,38 +52,65 @@ impl<'intermediate, 'parse> Registry<'intermediate, 'parse> {
.position(|(id, _definition)| *id == label)
{
if !definition.is_empty() {
let contents = convert_reference_contents(self, definition).await?;
let entry = self
.footnote_ids
.get_mut(existing_id)
.expect("If-statement proves this to be Some.");
entry.1 = FootnoteDefinitionContents::FromReference(definition);
entry.1 = contents;
}
existing_id
Ok(existing_id)
} else {
self.footnote_ids
.push((label, FootnoteDefinitionContents::FromReference(definition)));
self.footnote_ids.len() - 1
let contents = convert_reference_contents(self, definition).await?;
self.footnote_ids.push((label, contents));
Ok(self.footnote_ids.len() - 1)
}
}
/// Update the definition to a footnote but do not mark it as referenced.
pub(crate) fn register_footnote_definition<'b>(
pub(crate) async fn register_footnote_definition<'b>(
&'b mut self,
label: &'parse str,
definition: &'intermediate Vec<Element<'parse>>,
) {
if let Some((existing_id, existing_definition)) = self
definition: &'b Vec<Element<'parse>>,
) -> Result<(), CustomError> {
let contents = convert_definition_contents(self, definition).await?;
if let Some((_existing_id, existing_definition)) = self
.footnote_ids
.iter_mut()
.find(|(id, _definition)| *id == Some(label))
{
*existing_definition = FootnoteDefinitionContents::FromDefinition(definition);
*existing_definition = contents;
}
Ok(())
}
}
#[derive(Debug)]
pub(crate) enum FootnoteDefinitionContents<'intermediate, 'parse> {
FromReference(&'intermediate Vec<Object<'parse>>),
FromDefinition(&'intermediate Vec<Element<'parse>>),
async fn convert_reference_contents<'b, 'parse>(
registry: &'b mut Registry<'parse>,
contents: &'b Vec<Object<'parse>>,
) -> Result<Vec<IAstNode>, CustomError> {
let contents = {
let mut ret = Vec::new();
for obj in contents.iter() {
ret.push(obj.into_ast_node(registry).await?);
}
ret
};
Ok(contents)
}
async fn convert_definition_contents<'b, 'parse>(
registry: &'b mut Registry<'parse>,
contents: &'b Vec<Element<'parse>>,
) -> Result<Vec<IAstNode>, CustomError> {
let contents = {
let mut ret = Vec::new();
for obj in contents.iter() {
ret.push(obj.into_ast_node(registry).await?);
}
ret
};
Ok(contents)
}