From 4892ab97637c3727834248aba19b0407439c1f5f Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sat, 28 Jan 2023 19:56:11 +0200 Subject: refactor: only mutating methods on Markdown require mutable self Use RefCell's interior mutability to work around the fact that pandoc_ast's MutVisitor requires a mutable reference to self. Sponsored-by: author --- src/doc.rs | 2 +- src/md.rs | 38 +++++++++++++++++--------------------- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/src/doc.rs b/src/doc.rs index a39ab99..e860726 100644 --- a/src/doc.rs +++ b/src/doc.rs @@ -105,7 +105,7 @@ impl Document { subplot: PathBuf, markdowns: Vec, yamlmeta: &YamlMetadata, - mut md: Markdown, + md: Markdown, style: Style, template: Option<&str>, ) -> Result diff --git a/src/md.rs b/src/md.rs index 6f00ab7..59fdc1e 100644 --- a/src/md.rs +++ b/src/md.rs @@ -7,6 +7,7 @@ use crate::{ use log::trace; use pandoc_ast::{Map, MetaValue, MutVisitor, Pandoc}; use serde_yaml::{Mapping, Value}; +use std::cell::RefCell; use std::collections::HashSet; use std::convert::TryFrom; use std::path::{Path, PathBuf}; @@ -20,21 +21,19 @@ use visitor::LintingVisitor; /// A parsed Markdown document. #[derive(Debug)] pub struct Markdown { - pandoc: Pandoc, + pandoc: RefCell, } impl Markdown { fn new(pandoc: Pandoc) -> Self { - Self { pandoc } - } - - fn pandoc(&mut self) -> &mut Pandoc { - &mut self.pandoc + Self { + pandoc: RefCell::new(pandoc), + } } /// Set document metadata from subplot. pub fn set_metadata(&mut self, meta: &YamlMetadata) { - self.pandoc.meta = to_pandoc_meta(meta); + self.pandoc.borrow_mut().meta = to_pandoc_meta(meta); } /// JSON representation of Pandoc AST. @@ -44,17 +43,17 @@ impl Markdown { } /// Find problems. - pub fn lint(&mut self) -> Vec { + pub fn lint(&self) -> Vec { let mut linter = LintingVisitor::default(); - linter.walk_pandoc(self.pandoc()); + linter.walk_pandoc(&mut self.pandoc.borrow_mut()); linter.issues } /// Find included images. - pub fn images(&mut self) -> Vec { + pub fn images(&self) -> Vec { let mut names = vec![]; let mut visitor = visitor::ImageVisitor::new(); - visitor.walk_pandoc(self.pandoc()); + visitor.walk_pandoc(&mut self.pandoc.borrow_mut()); for x in visitor.images().iter() { names.push(x.to_path_buf()); } @@ -62,31 +61,28 @@ impl Markdown { } /// Find classes used for fenced blocks. - pub fn block_classes(&mut self) -> HashSet { + pub fn block_classes(&self) -> HashSet { let mut visitor = visitor::BlockClassVisitor::default(); - // Irritatingly we can't immutably visit the AST for some reason - // This clone() is expensive and unwanted, but I'm not sure how - // to get around it for now - visitor.walk_pandoc(self.pandoc()); + visitor.walk_pandoc(&mut self.pandoc.borrow_mut()); visitor.classes } /// Typeset. pub fn typeset(&mut self, style: Style, bindings: &Bindings) -> Vec { let mut visitor = visitor::TypesettingVisitor::new(style, bindings); - visitor.walk_pandoc(self.pandoc()); + visitor.walk_pandoc(&mut self.pandoc.borrow_mut()); visitor.warnings().warnings().to_vec() } /// Find scenarios. - pub fn scenarios(&mut self) -> Result, SubplotError> { + pub fn scenarios(&self) -> Result, SubplotError> { trace!( "Metadata::scenarios: looking for scenarios: {:#?}", self.pandoc ); let mut visitor = visitor::StructureVisitor::new(); - visitor.walk_pandoc(self.pandoc()); + visitor.walk_pandoc(&mut self.pandoc.borrow_mut()); trace!( "Metadata::scenarios: visitor found {} elements: {:#?}", visitor.elements.len(), @@ -108,9 +104,9 @@ impl Markdown { } /// Find embedded files. - pub fn embedded_files(&mut self) -> EmbeddedFiles { + pub fn embedded_files(&self) -> EmbeddedFiles { let mut files = EmbeddedFiles::default(); - files.walk_pandoc(self.pandoc()); + files.walk_pandoc(&mut self.pandoc.borrow_mut()); files } } -- cgit v1.2.1