Fix build by making the registry guarded by an ArcMutex.

This commit is contained in:
Tom Alexander 2023-10-29 21:19:30 -04:00
parent f63620b547
commit 1f3b5262b8
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
15 changed files with 113 additions and 90 deletions

View File

@ -1,5 +1,7 @@
use std::path::Path; use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::Arc;
use std::sync::Mutex;
use tokio::task::JoinHandle; use tokio::task::JoinHandle;
use walkdir::WalkDir; use walkdir::WalkDir;
@ -58,14 +60,11 @@ impl BlogPost {
_ => {} _ => {}
}); });
let registry = Arc::new(Mutex::new(registry));
let relative_to_post_dir_path = real_path.strip_prefix(post_dir)?; let relative_to_post_dir_path = real_path.strip_prefix(post_dir)?;
ret.push( ret.push(
BlogPostPage::new( BlogPostPage::new(relative_to_post_dir_path, registry, parsed_document)
relative_to_post_dir_path, .await?,
&mut registry,
parsed_document,
)
.await?,
); );
} }
ret ret

View File

@ -1,7 +1,9 @@
use super::macros::intermediate; use super::macros::intermediate;
use super::registry::register_footnote_definition;
use super::registry::Registry; use super::registry::Registry;
use super::IAstNode; use super::IAstNode;
use crate::error::CustomError; use crate::error::CustomError;
use crate::intermediate::RefRegistry;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct IFootnoteDefinition {} pub(crate) struct IFootnoteDefinition {}
@ -12,9 +14,7 @@ intermediate!(
original, original,
registry, registry,
{ {
registry register_footnote_definition(registry, original.label, &original.children).await?;
.register_footnote_definition(original.label, &original.children)
.await?;
Ok(IFootnoteDefinition {}) Ok(IFootnoteDefinition {})
} }
); );
@ -26,8 +26,8 @@ pub(crate) struct IRealFootnoteDefinition {
} }
impl IRealFootnoteDefinition { impl IRealFootnoteDefinition {
pub(crate) async fn new<'reg, 'orig, 'parse>( pub(crate) async fn new<'orig, 'parse>(
registry: &'reg mut Registry<'orig, 'parse>, registry: RefRegistry<'orig, 'parse>,
footnote_id: usize, footnote_id: usize,
contents: Vec<IAstNode>, contents: Vec<IAstNode>,
) -> Result<IRealFootnoteDefinition, CustomError> { ) -> Result<IRealFootnoteDefinition, CustomError> {

View File

@ -1,4 +1,5 @@
use super::macros::intermediate; use super::macros::intermediate;
use super::registry::get_footnote_reference_id;
use super::registry::Registry; use super::registry::Registry;
use crate::error::CustomError; use crate::error::CustomError;
@ -9,9 +10,8 @@ pub(crate) struct IFootnoteReference {
} }
intermediate!(IFootnoteReference, FootnoteReference, original, registry, { intermediate!(IFootnoteReference, FootnoteReference, original, registry, {
let footnote_id = registry let footnote_id =
.get_footnote_reference_id(original.label, &original.definition) get_footnote_reference_id(registry, original.label, &original.definition).await?;
.await?;
Ok(IFootnoteReference { Ok(IFootnoteReference {
footnote_id, footnote_id,
duplicate_offset: 0, // TODO duplicate_offset: 0, // TODO

View File

@ -15,14 +15,14 @@ intermediate!(IHeading, Heading, original, registry, {
let title = { let title = {
let mut ret = Vec::new(); let mut ret = Vec::new();
for obj in original.title.iter() { for obj in original.title.iter() {
ret.push(IObject::new(registry, obj).await?); ret.push(IObject::new(registry.clone(), obj).await?);
} }
ret ret
}; };
let children = { let children = {
let mut ret = Vec::new(); let mut ret = Vec::new();
for obj in original.children.iter() { for obj in original.children.iter() {
ret.push(IDocumentElement::new(registry, obj).await?); ret.push(IDocumentElement::new(registry.clone(), obj).await?);
} }
ret ret
}; };

View File

@ -8,7 +8,7 @@ macro_rules! inoop {
impl $istruct { impl $istruct {
pub(crate) async fn new<'reg, 'orig, 'parse>( pub(crate) async fn new<'reg, 'orig, 'parse>(
registry: &'reg mut Registry<'orig, 'parse>, registry: crate::intermediate::RefRegistry<'orig, 'parse>,
original: &'orig organic::types::$pstruct<'parse>, original: &'orig organic::types::$pstruct<'parse>,
) -> Result<$istruct, CustomError> { ) -> Result<$istruct, CustomError> {
Ok($istruct {}) Ok($istruct {})
@ -25,8 +25,8 @@ pub(crate) use inoop;
macro_rules! intermediate { macro_rules! intermediate {
($istruct:ident, $pstruct:ident, $original:ident, $registry:ident, $fnbody:tt) => { ($istruct:ident, $pstruct:ident, $original:ident, $registry:ident, $fnbody:tt) => {
impl $istruct { impl $istruct {
pub(crate) async fn new<'reg, 'orig, 'parse>( pub(crate) async fn new<'orig, 'parse>(
registry: &'reg mut Registry<'orig, 'parse>, registry: crate::intermediate::RefRegistry<'orig, 'parse>,
original: &'orig organic::types::$pstruct<'parse>, original: &'orig organic::types::$pstruct<'parse>,
) -> Result<$istruct, CustomError> { ) -> Result<$istruct, CustomError> {
let $original = original; let $original = original;
@ -45,10 +45,10 @@ pub(crate) use intermediate;
macro_rules! iselector { macro_rules! iselector {
($istruct:ident, $pstruct:ident, $original:ident, $registry:ident, $fnbody:tt) => { ($istruct:ident, $pstruct:ident, $original:ident, $registry:ident, $fnbody:tt) => {
impl $istruct { impl $istruct {
pub(crate) fn new<'reg: 'orig, 'orig, 'parse, 'inp: 'reg + 'orig>( pub(crate) fn new<'orig, 'parse>(
registry: &'reg mut Registry<'orig, 'parse>, registry: crate::intermediate::RefRegistry<'orig, 'parse>,
original: &'orig organic::types::$pstruct<'parse>, original: &'orig organic::types::$pstruct<'parse>,
) -> BoxFuture<'inp, Result<$istruct, CustomError>> { ) -> BoxFuture<'orig, Result<$istruct, CustomError>> {
let $registry = registry; let $registry = registry;
let $original = original; let $original = original;
async move { $fnbody }.boxed() async move { $fnbody }.boxed()
@ -64,7 +64,7 @@ macro_rules! iitem {
match $original { match $original {
$( $(
$penum(inner) => Ok($ienum( $penum(inner) => Ok($ienum(
$istruct::new($registry, inner).await?, $istruct::new($registry.clone(), inner).await?,
)), )),
)* )*
} }

View File

@ -124,3 +124,6 @@ pub(crate) use timestamp::ITimestamp;
pub(crate) use underline::IUnderline; pub(crate) use underline::IUnderline;
pub(crate) use verbatim::IVerbatim; pub(crate) use verbatim::IVerbatim;
pub(crate) use verse_block::IVerseBlock; pub(crate) use verse_block::IVerseBlock;
pub(crate) type RefRegistry<'orig, 'parse> =
std::sync::Arc<std::sync::Mutex<registry::Registry<'orig, 'parse>>>;

View File

@ -7,6 +7,7 @@ use super::registry::Registry;
use super::IDocumentElement; use super::IDocumentElement;
use super::IHeading; use super::IHeading;
use super::ISection; use super::ISection;
use super::RefRegistry;
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct BlogPostPage { pub(crate) struct BlogPostPage {
@ -24,30 +25,34 @@ impl BlogPostPage {
// TODO: Move path into the registry so I can give this a standard interface like the others. // TODO: Move path into the registry so I can give this a standard interface like the others.
pub(crate) async fn new<'a, 'b, 'parse, P: Into<PathBuf>>( pub(crate) async fn new<'a, 'b, 'parse, P: Into<PathBuf>>(
path: P, path: P,
registry: &'a mut Registry<'b, 'parse>, registry: RefRegistry<'b, 'parse>,
document: &'b organic::types::Document<'parse>, document: &'b organic::types::Document<'parse>,
) -> Result<BlogPostPage, CustomError> { ) -> Result<BlogPostPage, CustomError> {
let path = path.into(); let path = path.into();
let mut children = Vec::new(); let mut children = Vec::new();
if let Some(section) = document.zeroth_section.as_ref() { if let Some(section) = document.zeroth_section.as_ref() {
children.push(IDocumentElement::Section( children.push(IDocumentElement::Section(
ISection::new(registry, section).await?, ISection::new(registry.clone(), section).await?,
)); ));
} }
for heading in document.children.iter() { for heading in document.children.iter() {
children.push(IDocumentElement::Heading( children.push(IDocumentElement::Heading(
IHeading::new(registry, heading).await?, IHeading::new(registry.clone(), heading).await?,
)); ));
} }
let footnotes = { let footnotes = {
let footnote_definitions: Vec<_> = registry let footnote_definitions: Vec<_> = {
.get_footnote_ids() let registry = registry.lock().unwrap();
.map(|(id, def)| (id, def.clone())) let ret = registry
.collect(); .get_footnote_ids()
.map(|(id, def)| (id, def.clone()))
.collect();
ret
};
let mut ret = Vec::new(); let mut ret = Vec::new();
for (id, def) in footnote_definitions.into_iter() { for (id, def) in footnote_definitions.into_iter() {
ret.push(IRealFootnoteDefinition::new(registry, id, def).await?); ret.push(IRealFootnoteDefinition::new(registry.clone(), id, def).await?);
} }
ret ret
}; };

View File

@ -12,7 +12,7 @@ intermediate!(IParagraph, Paragraph, original, registry, {
let children = { let children = {
let mut ret = Vec::new(); let mut ret = Vec::new();
for obj in original.children.iter() { for obj in original.children.iter() {
ret.push(IObject::new(registry, obj).await?); ret.push(IObject::new(registry.clone(), obj).await?);
} }
ret ret
}; };

View File

@ -13,7 +13,7 @@ intermediate!(IPlainList, PlainList, original, registry, {
let children = { let children = {
let mut ret = Vec::new(); let mut ret = Vec::new();
for obj in original.children.iter() { for obj in original.children.iter() {
ret.push(IPlainListItem::new(registry, obj).await?); ret.push(IPlainListItem::new(registry.clone(), obj).await?);
} }
ret ret
}; };

View File

@ -14,7 +14,7 @@ intermediate!(IPlainListItem, PlainListItem, original, registry, {
let tag = { let tag = {
let mut ret = Vec::new(); let mut ret = Vec::new();
for obj in original.tag.iter() { for obj in original.tag.iter() {
ret.push(IObject::new(registry, obj).await?); ret.push(IObject::new(registry.clone(), obj).await?);
} }
ret ret
}; };
@ -22,7 +22,7 @@ intermediate!(IPlainListItem, PlainListItem, original, registry, {
let children = { let children = {
let mut ret = Vec::new(); let mut ret = Vec::new();
for elem in original.children.iter() { for elem in original.children.iter() {
ret.push(IElement::new(registry, elem).await?); ret.push(IElement::new(registry.clone(), elem).await?);
} }
ret ret
}; };

View File

@ -12,7 +12,7 @@ intermediate!(IQuoteBlock, QuoteBlock, original, registry, {
let children = { let children = {
let mut ret = Vec::new(); let mut ret = Vec::new();
for obj in original.children.iter() { for obj in original.children.iter() {
ret.push(IElement::new(registry, obj).await?); ret.push(IElement::new(registry.clone(), obj).await?);
} }
ret ret
}; };

View File

@ -1,5 +1,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::sync::Arc;
use std::sync::Mutex;
// use super::ast_node::IntoIAstNode; // use super::ast_node::IntoIAstNode;
use crate::error::CustomError; use crate::error::CustomError;
@ -7,6 +9,7 @@ use organic::types::Element;
use organic::types::Object; use organic::types::Object;
use super::ast_node::IAstNode; use super::ast_node::IAstNode;
use super::RefRegistry;
type IdCounter = u16; type IdCounter = u16;
@ -40,63 +43,75 @@ impl<'orig, 'parse> Registry<'orig, 'parse> {
.map(|(_label, definition)| definition) .map(|(_label, definition)| definition)
.enumerate() .enumerate()
} }
}
/// Get a 0-indexed ID for a footnote. /// Get a 0-indexed ID for a footnote.
/// ///
/// This needs to be incremented to be 1-indexed for render. /// This needs to be incremented to be 1-indexed for render.
pub(crate) async fn get_footnote_reference_id<'reg>( pub(crate) async fn get_footnote_reference_id<'orig, 'parse>(
&'reg mut self, registry: RefRegistry<'orig, 'parse>,
label: Option<&'parse str>, label: Option<&'parse str>,
definition: &'orig Vec<Object<'parse>>, definition: &'orig Vec<Object<'parse>>,
) -> Result<usize, CustomError> { ) -> Result<usize, CustomError> {
if let None = label { if let None = label {
// If it has no label then it must always get a new ID. // If it has no label then it must always get a new ID.
let contents = convert_reference_contents(self, definition).await?; let contents = convert_reference_contents(registry.clone(), definition).await?;
self.footnote_ids.push((None, contents)); let pos = {
return Ok(self.footnote_ids.len() - 1); let mut registry = registry.lock().unwrap();
} registry.footnote_ids.push((None, contents));
registry.footnote_ids.len() - 1
if let Some(existing_id) = self };
.footnote_ids return Ok(pos);
.iter()
.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 = contents;
}
Ok(existing_id)
} else {
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. let existing_index = registry
pub(crate) async fn register_footnote_definition<'reg>( .lock()
&'reg mut self, .unwrap()
label: &'parse str, .footnote_ids
definition: &'orig Vec<Element<'parse>>, .iter()
) -> Result<(), CustomError> { .position(|(id, _definition)| *id == label);
let contents = convert_definition_contents(self, definition).await?; if let Some(existing_id) = existing_index {
if let Some((_existing_id, existing_definition)) = self if !definition.is_empty() {
.footnote_ids let contents = convert_reference_contents(registry.clone(), definition).await?;
.iter_mut() let mut registry = registry.lock().unwrap();
.find(|(id, _definition)| *id == Some(label)) let entry = registry
{ .footnote_ids
*existing_definition = contents; .get_mut(existing_id)
.expect("If-statement proves this to be Some.");
entry.1 = contents;
} }
Ok(()) Ok(existing_id)
} else {
let contents = convert_reference_contents(registry.clone(), definition).await?;
let pos = {
let mut registry = registry.lock().unwrap();
registry.footnote_ids.push((label, contents));
registry.footnote_ids.len() - 1
};
Ok(pos)
} }
} }
async fn convert_reference_contents<'reg, 'orig, 'parse>( /// Update the definition to a footnote but do not mark it as referenced.
registry: &'reg mut Registry<'orig, 'parse>, pub(crate) async fn register_footnote_definition<'orig, 'parse>(
registry: RefRegistry<'orig, 'parse>,
label: &'parse str,
definition: &'orig Vec<Element<'parse>>,
) -> Result<(), CustomError> {
let contents = convert_definition_contents(registry.clone(), definition).await?;
let mut registry = registry.lock().unwrap();
if let Some((_existing_id, existing_definition)) = registry
.footnote_ids
.iter_mut()
.find(|(id, _definition)| *id == Some(label))
{
*existing_definition = contents;
}
Ok(())
}
async fn convert_reference_contents<'orig, 'parse>(
registry: RefRegistry<'orig, 'parse>,
contents: &'orig Vec<Object<'parse>>, contents: &'orig Vec<Object<'parse>>,
) -> Result<Vec<IAstNode>, CustomError> { ) -> Result<Vec<IAstNode>, CustomError> {
let contents = { let contents = {
@ -111,8 +126,8 @@ async fn convert_reference_contents<'reg, 'orig, 'parse>(
Ok(contents) Ok(contents)
} }
async fn convert_definition_contents<'reg, 'orig, 'parse>( async fn convert_definition_contents<'orig, 'parse>(
registry: &'reg mut Registry<'orig, 'parse>, registry: RefRegistry<'orig, 'parse>,
contents: &'orig Vec<Element<'parse>>, contents: &'orig Vec<Element<'parse>>,
) -> Result<Vec<IAstNode>, CustomError> { ) -> Result<Vec<IAstNode>, CustomError> {
let contents = { let contents = {

View File

@ -13,7 +13,7 @@ intermediate!(IRegularLink, RegularLink, original, registry, {
let children = { let children = {
let mut ret = Vec::new(); let mut ret = Vec::new();
for obj in original.children.iter() { for obj in original.children.iter() {
ret.push(IObject::new(registry, obj).await?); ret.push(IObject::new(registry.clone(), obj).await?);
} }
ret ret
}; };

View File

@ -12,7 +12,7 @@ intermediate!(ISection, Section, original, registry, {
let children = { let children = {
let mut ret = Vec::new(); let mut ret = Vec::new();
for elem in original.children.iter() { for elem in original.children.iter() {
ret.push(IElement::new(registry, elem).await?); ret.push(IElement::new(registry.clone(), elem).await?);
} }
ret ret
}; };

View File

@ -9,6 +9,7 @@ pub(crate) struct ITarget {
} }
intermediate!(ITarget, Target, original, registry, { intermediate!(ITarget, Target, original, registry, {
let mut registry = registry.lock().unwrap();
let id = registry.get_target(original.value); let id = registry.get_target(original.value);
Ok(ITarget { Ok(ITarget {
id: id.clone(), id: id.clone(),