Skip to content

Commit

Permalink
Processing end interval
Browse files Browse the repository at this point in the history
  • Loading branch information
oovm committed Oct 30, 2023
1 parent 3b95da8 commit 1ec8b1f
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 29 deletions.
8 changes: 4 additions & 4 deletions projects/code-span/src/view/iter.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{collections::BTreeSet, ops::Range};
use std::ops::Range;

use crate::view::{CodeRender, CodeView, InnerSpan};
use crate::view::{CodeRender, CodeView, IntervalRepr};

/// # Arguments
///
Expand All @@ -17,15 +17,15 @@ use crate::view::{CodeRender, CodeView, InnerSpan};
#[derive(Debug)]
pub struct CodeRendered<'r, 'i, 's> {
text: &'i str,
iter: std::collections::btree_map::Iter<'r, usize, InnerSpan<'s>>,
iter: std::collections::btree_map::Iter<'r, usize, IntervalRepr<'s>>,
}

impl<'r, 'i, 's> IntoIterator for &'r CodeRender<'i, 's> {
type Item = CodeView<'r, 'i, 's>;
type IntoIter = CodeRendered<'r, 'i, 's>;

fn into_iter(self) -> Self::IntoIter {
CodeRendered { text: self.text, iter: self.interval.iter() }
CodeRendered { text: self.text, iter: self.intervals.iter() }
}
}

Expand Down
66 changes: 41 additions & 25 deletions projects/code-span/src/view/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,62 +11,78 @@ pub struct CodeRender<'i, 's> {
/// raw text
text: &'i str,
/// start -> (styles , end)
interval: BTreeMap<usize, InnerSpan<'s>>,
intervals: BTreeMap<usize, IntervalRepr<'s>>,
}

#[derive(Clone, Debug)]
struct InnerSpan<'s> {
struct IntervalRepr<'s> {
styles: BTreeSet<&'s str>,
end: usize,
}

#[derive(Copy, Clone, Debug)]
pub struct CodeView<'r, 'i, 's> {
pub text: &'i str,
pub kind: &'r BTreeSet<&'s str>,
}

impl<'i, 's> CodeRender<'i, 's> {
pub fn new(text: &'i str) -> Self {
let mut interval = BTreeMap::new();
interval.insert(0, InnerSpan { styles: Default::default(), end: text.len() });
Self { text, interval }
interval.insert(0, IntervalRepr { styles: Default::default(), end: text.len() });
Self { text, intervals: interval }
}
pub fn get_span<'r>(&'r mut self, offset: usize) -> Option<CodeView<'r, 'i, 's>> {
let (start, span) = self.interval.range(offset..).next()?;
let (start, span) = self.intervals.range(offset..).next()?;
let range = Range { start: *start, end: span.end };
let text = self.text.get(range.clone())?;
Some(CodeView { text, kind: &span.styles })
}
pub fn mark_span(&mut self, span: Range<usize>, style: &'s str) {
match self.interval.get(&span.start) {
match self.intervals.get(&span.start) {
Some(_) => {
match self.interval.get(&span.end) {
// easy case, no need modifier old interval
Some(_) => self.interval.range_mut(span).for_each(|(_, inner)| {
inner.styles.insert(style);
}),
match self.intervals.get(&span.end) {
// simple case, no need change old interval
Some(_) => self.mark_span_unchecked(span, style),
// remark end position
None => {
todo!()
let (_, last_span) = self.intervals.range(span.end..).next().unwrap();
let new_end = last_span.end;
let new_styles = last_span.styles.clone();
self.intervals.remove(&span.end);
self.intervals.entry(span.end).or_insert(IntervalRepr { styles: new_styles, end: new_end });
self.mark_span_unchecked(span, style)
}
}
}
None => {
// 修改前一个区间的结束位置
self.interval.range_mut(..span.start).next_back().map(|(_, v)| {
v.end = span.start;
});
todo!()
// truncate the previous span
let prev_span = self.intervals.range_mut(..span.start).next_back();
if let Some((_, prev_inner)) = prev_span {
prev_inner.end = span.start;
}
// insert start position
let (_, next_span) = self.intervals.range(span.start..).next().unwrap();
let new_end = next_span.end;
let new_styles = next_span.styles.clone();
self.intervals.remove(&span.start);
self.intervals.entry(span.start).or_insert(IntervalRepr { styles: new_styles, end: new_end });
self.mark_span_unchecked(span, style)
}
}
}
fn mark_span_unchecked(&mut self, span: Range<usize>, style: &'s str) {
for (_, inner) in self.intervals.range_mut(span) {
inner.styles.insert(style);
}
}
}

#[test]
fn main() {
let mut code_render = CodeRender::new("public class Main {}");
code_render.mark_span(0..17, "class");
code_render.mark_span(0..3, "keyword");
code_render.mark_span(0..6, "keyword");
code_render.mark_span(7..12, "keyword");
code_render.mark_span(13..17, "class");
println!("{:#?}", code_render);
}

#[derive(Copy, Clone, Debug)]
pub struct CodeView<'r, 'i, 's> {
pub text: &'i str,
pub kind: &'r BTreeSet<&'s str>,
}

0 comments on commit 1ec8b1f

Please sign in to comment.