Implement iterator for context.
This commit is contained in:
parent
22e9bc991f
commit
0d728510d7
16
src/context/global_settings.rs
Normal file
16
src/context/global_settings.rs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#[derive(Debug)]
|
||||||
|
pub struct GlobalSettings<'s> {
|
||||||
|
placeholder: Option<&'s str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'s> GlobalSettings<'s> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
GlobalSettings { placeholder: None }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'s> Default for GlobalSettings<'s> {
|
||||||
|
fn default() -> Self {
|
||||||
|
GlobalSettings::new()
|
||||||
|
}
|
||||||
|
}
|
@ -27,6 +27,10 @@ impl<'parent, T> List<'parent, T> {
|
|||||||
pub fn iter(&self) -> Iter<'_, T> {
|
pub fn iter(&self) -> Iter<'_, T> {
|
||||||
Iter { next: Some(self) }
|
Iter { next: Some(self) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn iter_list(&self) -> IterList<'_, T> {
|
||||||
|
Iter { next: Some(self) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ListType<'parent, T> {
|
pub trait ListType<'parent, T> {
|
||||||
@ -64,3 +68,17 @@ impl<'a, T> Iterator for Iter<'a, T> {
|
|||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct IterList<'a, T> {
|
||||||
|
next: Link<'a, T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> Iterator for IterList<'a, T> {
|
||||||
|
type Item = &'a List<'a, T>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let ret = self.next;
|
||||||
|
self.next = self.next.map(|this| this.get_parent()).flatten();
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@ use crate::error::Res;
|
|||||||
use crate::parser::OrgSource;
|
use crate::parser::OrgSource;
|
||||||
|
|
||||||
mod exiting;
|
mod exiting;
|
||||||
|
mod global_settings;
|
||||||
mod list;
|
mod list;
|
||||||
mod parser_context;
|
mod parser_context;
|
||||||
mod parser_with_context;
|
mod parser_with_context;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use nom::combinator::eof;
|
use nom::combinator::eof;
|
||||||
|
|
||||||
use super::exiting::ExitClass;
|
use super::exiting::ExitClass;
|
||||||
|
use super::global_settings::GlobalSettings;
|
||||||
use super::list::List;
|
use super::list::List;
|
||||||
use super::DynContextMatcher;
|
use super::DynContextMatcher;
|
||||||
use crate::error::Res;
|
use crate::error::Res;
|
||||||
@ -128,33 +129,16 @@ impl<'r> std::fmt::Debug for ExitMatcherNode<'r> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct GlobalSettings<'s> {
|
|
||||||
placeholder: Option<&'s str>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'s> GlobalSettings<'s> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
GlobalSettings { placeholder: None }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'s> Default for GlobalSettings<'s> {
|
|
||||||
fn default() -> Self {
|
|
||||||
GlobalSettings::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Context<'r, 's> {
|
pub struct Context<'r, 's> {
|
||||||
global_settings: &'s GlobalSettings<'s>,
|
global_settings: &'s GlobalSettings<'s>,
|
||||||
tree: List<'r, ContextElement<'r, 's>>,
|
tree: &'r List<'r, ContextElement<'r, 's>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'r, 's> Context<'r, 's> {
|
impl<'r, 's> Context<'r, 's> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
global_settings: &'s GlobalSettings<'s>,
|
global_settings: &'s GlobalSettings<'s>,
|
||||||
tree: List<'r, ContextElement<'r, 's>>,
|
tree: &'r List<'r, ContextElement<'r, 's>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
global_settings,
|
global_settings,
|
||||||
@ -162,16 +146,6 @@ impl<'r, 's> Context<'r, 's> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn document_context(global_settings: &'s GlobalSettings<'s>) -> Self {
|
|
||||||
Context::new(
|
|
||||||
global_settings,
|
|
||||||
List::new(ContextElement::ExitMatcherNode(ExitMatcherNode {
|
|
||||||
exit_matcher: &document_end,
|
|
||||||
class: ExitClass::Document,
|
|
||||||
})),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn with_additional_node(&self, data: ContextElement<'r, 's>) -> Self {
|
pub fn with_additional_node(&self, data: ContextElement<'r, 's>) -> Self {
|
||||||
let new_tree = self.tree.push(data);
|
let new_tree = self.tree.push(data);
|
||||||
Self {
|
Self {
|
||||||
@ -179,6 +153,24 @@ impl<'r, 's> Context<'r, 's> {
|
|||||||
tree: new_tree,
|
tree: new_tree,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn iter(&self) -> super::list::Iter<'r, ContextElement<'r, 's>> {
|
||||||
|
self.tree.iter()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter_context(&self) -> Iter<'r, 's> {
|
||||||
|
Iter {
|
||||||
|
next: self.tree.iter_list(),
|
||||||
|
global_settings: self.global_settings,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_parent(&self) -> Option<Self> {
|
||||||
|
self.tree.get_parent().map(|parent_tree| Self {
|
||||||
|
global_settings: self.global_settings,
|
||||||
|
tree: parent_tree,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
#[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))]
|
||||||
@ -188,3 +180,27 @@ fn document_end<'r, 's>(
|
|||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
eof(input)
|
eof(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Iter<'r, 's> {
|
||||||
|
global_settings: &'s GlobalSettings<'s>,
|
||||||
|
next: super::list::IterList<'r, ContextElement<'r, 's>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'r, 's> Iterator for Iter<'r, 's> {
|
||||||
|
type Item = Context<'r, 's>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let next_tree = self.next.next();
|
||||||
|
let ret = next_tree.map(|parent_tree| Context::new(self.global_settings, parent_tree));
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'r, 's> ContextElement<'r, 's> {
|
||||||
|
pub fn document_context() -> Self {
|
||||||
|
Self::ExitMatcherNode(ExitMatcherNode {
|
||||||
|
exit_matcher: &document_end,
|
||||||
|
class: ExitClass::Document,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -399,10 +399,9 @@ fn time_range_rest_end<'r, 's>(
|
|||||||
input: OrgSource<'s>,
|
input: OrgSource<'s>,
|
||||||
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
) -> Res<OrgSource<'s>, OrgSource<'s>> {
|
||||||
// We pop off the most recent context element to get a context tree with just the active/inactive_time_rest_end exit matcher (removing this function from the exit matcher chain) because the 2nd time in the range does not end when a "-TIME" pattern is found.
|
// We pop off the most recent context element to get a context tree with just the active/inactive_time_rest_end exit matcher (removing this function from the exit matcher chain) because the 2nd time in the range does not end when a "-TIME" pattern is found.
|
||||||
let parent_node = context.iter().next().expect("Two context elements are added to the tree when adding this exit matcher, so it should be impossible for this to return None.");
|
let parent_node = context.get_parent().expect("Two context elements are added to the tree when adding this exit matcher, so it should be impossible for this to return None.");
|
||||||
let parent_tree = ContextTree::branch_from(parent_node);
|
|
||||||
let exit_contents =
|
let exit_contents =
|
||||||
recognize(tuple((tag("-"), parser_with_context!(time)(&parent_tree))))(input);
|
recognize(tuple((tag("-"), parser_with_context!(time)(&parent_node))))(input);
|
||||||
exit_contents
|
exit_contents
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
use super::Element;
|
use crate::types::Document;
|
||||||
use super::Object;
|
use crate::types::DocumentElement;
|
||||||
use super::PlainListItem;
|
use crate::types::Element;
|
||||||
use super::TableCell;
|
use crate::types::Heading;
|
||||||
use super::TableRow;
|
use crate::types::Object;
|
||||||
|
use crate::types::PlainListItem;
|
||||||
|
use crate::types::Section;
|
||||||
|
use crate::types::TableCell;
|
||||||
|
use crate::types::TableRow;
|
||||||
|
|
||||||
pub enum Token<'r, 's> {
|
pub enum Token<'r, 's> {
|
||||||
Document(&'r Document<'s>),
|
Document(&'r Document<'s>),
|
||||||
|
@ -14,7 +14,9 @@ use nom::multi::many_till;
|
|||||||
use nom::sequence::tuple;
|
use nom::sequence::tuple;
|
||||||
|
|
||||||
use super::org_source::OrgSource;
|
use super::org_source::OrgSource;
|
||||||
use super::Context;
|
use crate::context::parser_with_context;
|
||||||
|
use crate::context::ContextElement;
|
||||||
|
use crate::context::RefContext;
|
||||||
use crate::error::CustomError;
|
use crate::error::CustomError;
|
||||||
use crate::error::MyError;
|
use crate::error::MyError;
|
||||||
use crate::error::Res;
|
use crate::error::Res;
|
||||||
@ -35,7 +37,10 @@ pub fn in_section<'r, 's, 'x>(context: RefContext<'r, 's>, section_name: &'x str
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if we are currently an immediate child of the given section type
|
/// Checks if we are currently an immediate child of the given section type
|
||||||
pub fn immediate_in_section<'r, 's, 'x>(context: RefContext<'r, 's>, section_name: &'x str) -> bool {
|
pub fn immediate_in_section<'r, 's, 'x>(
|
||||||
|
context: RefContext<'r, 's>,
|
||||||
|
section_name: &'x str,
|
||||||
|
) -> bool {
|
||||||
for thing in context.iter() {
|
for thing in context.iter() {
|
||||||
match thing.get_data() {
|
match thing.get_data() {
|
||||||
ContextElement::Context(name) if *name == section_name => return true,
|
ContextElement::Context(name) if *name == section_name => return true,
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use super::Element;
|
||||||
|
use super::Object;
|
||||||
use super::Source;
|
use super::Source;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -19,6 +19,8 @@ use super::lesser_element::Planning;
|
|||||||
use super::lesser_element::SrcBlock;
|
use super::lesser_element::SrcBlock;
|
||||||
use super::lesser_element::VerseBlock;
|
use super::lesser_element::VerseBlock;
|
||||||
use super::Drawer;
|
use super::Drawer;
|
||||||
|
use super::SetSource;
|
||||||
|
use super::Source;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Element<'s> {
|
pub enum Element<'s> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user