Remove AttrsList lifetime bound

This commit is contained in:
Jeremy Soller 2022-11-04 09:44:54 -06:00
parent 06cb0c2637
commit ac354c3a2a
No known key found for this signature in database
GPG key ID: 87F211AF2BE4C2FE
6 changed files with 114 additions and 44 deletions

View file

@ -51,6 +51,40 @@ impl Color {
}
}
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum FamilyOwned {
Name(String),
Serif,
SansSerif,
Cursive,
Fantasy,
Monospace,
}
impl FamilyOwned {
pub fn new(family: Family) -> Self {
match family {
Family::Name(name) => FamilyOwned::Name(name.to_string()),
Family::Serif => FamilyOwned::Serif,
Family::SansSerif => FamilyOwned::SansSerif,
Family::Cursive => FamilyOwned::Cursive,
Family::Fantasy => FamilyOwned::Fantasy,
Family::Monospace => FamilyOwned::Monospace,
}
}
pub fn as_family(&self) -> Family {
match self {
FamilyOwned::Name(name) => Family::Name(&name),
FamilyOwned::Serif => Family::Serif,
FamilyOwned::SansSerif => Family::SansSerif,
FamilyOwned::Cursive => Family::Cursive,
FamilyOwned::Fantasy => Family::Fantasy,
FamilyOwned::Monospace => Family::Monospace,
}
}
}
/// Text attributes
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct Attrs<'a> {
@ -136,30 +170,65 @@ impl<'a> Attrs<'a> {
}
}
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct AttrsOwned {
//TODO: should this be an option?
pub color_opt: Option<Color>,
pub family_owned: FamilyOwned,
pub monospaced: bool,
pub stretch: Stretch,
pub style: Style,
pub weight: Weight,
}
impl AttrsOwned {
pub fn new(attrs: Attrs) -> Self {
Self {
color_opt: attrs.color_opt,
family_owned: FamilyOwned::new(attrs.family),
monospaced: attrs.monospaced,
stretch: attrs.stretch,
style: attrs.style,
weight: attrs.weight,
}
}
pub fn as_attrs(&self) -> Attrs {
Attrs {
color_opt: self.color_opt,
family: self.family_owned.as_family(),
monospaced: self.monospaced,
stretch: self.stretch,
style: self.style,
weight: self.weight,
}
}
}
/// List of text attributes to apply to a line
//TODO: have this clean up the spans when changes are made
#[derive(Eq, PartialEq)]
pub struct AttrsList<'a> {
defaults: Attrs<'a>,
spans: Vec<(Range<usize>, Attrs<'a>)>,
pub struct AttrsList {
defaults: AttrsOwned,
spans: Vec<(Range<usize>, AttrsOwned)>,
}
impl<'a> AttrsList<'a> {
impl AttrsList {
/// Create a new attributes list with a set of default [Attrs]
pub fn new(defaults: Attrs<'a>) -> Self {
pub fn new(defaults: Attrs) -> Self {
Self {
defaults,
defaults: AttrsOwned::new(defaults),
spans: Vec::new(),
}
}
/// Get the default [Attrs]
pub fn defaults(&self) -> Attrs<'a> {
self.defaults
pub fn defaults(&self) -> Attrs {
self.defaults.as_attrs()
}
/// Get the current attribute spans
pub fn spans(&self) -> &Vec<(Range<usize>, Attrs<'a>)> {
pub fn spans(&self) -> &Vec<(Range<usize>, AttrsOwned)> {
&self.spans
}
@ -169,7 +238,7 @@ impl<'a> AttrsList<'a> {
}
/// Add an attribute span, removes any previous matching parts of spans
pub fn add_span(&mut self, range: Range<usize>, attrs: Attrs<'a>) {
pub fn add_span(&mut self, range: Range<usize>, attrs: Attrs) {
//do not support 1..1 even if by accident.
if range.start == range.end {
return;
@ -191,7 +260,7 @@ impl<'a> AttrsList<'a> {
rework_spans.push((rework.0.start..range.start, rework.1))
} else if self.spans[i].0.end > range.end && self.spans[i].0.start < range.start {
let rework = self.spans.remove(i);
rework_spans.push((rework.0.start..range.start, rework.1));
rework_spans.push((rework.0.start..range.start, rework.1.clone()));
rework_spans.push((range.end..rework.0.end, rework.1));
} else if self.spans[i].0.start > range.end {
break;
@ -208,7 +277,7 @@ impl<'a> AttrsList<'a> {
// Combine span if possible
let mut combined = false;
for span in self.spans.iter_mut() {
if span.1 != attrs {
if span.1.as_attrs() != attrs {
// Ignore not matching attrs
continue;
}
@ -230,7 +299,7 @@ impl<'a> AttrsList<'a> {
if ! combined {
//Finally lets add the new span. it should fit now.
self.spans.push((range, attrs));
self.spans.push((range, AttrsOwned::new(attrs)));
}
//sort by start to speed up further additions
@ -240,18 +309,18 @@ impl<'a> AttrsList<'a> {
/// Get the highest priority attribute span for a range
///
/// This returns the first span that contains the range
pub fn get_span(&self, range: Range<usize>) -> Attrs<'a> {
pub fn get_span(&self, range: Range<usize>) -> Attrs {
for span in self.spans.iter() {
if range.start >= span.0.start && range.end <= span.0.end {
return span.1;
return span.1.as_attrs();
}
}
self.defaults
self.defaults.as_attrs()
}
/// Split attributes list at an offset
pub fn split_off(&mut self, index: usize) -> Self {
let mut new = Self::new(self.defaults);
let mut new = Self::new(self.defaults.as_attrs());
let mut i = 0;
while i < self.spans.len() {
if self.spans[i].0.end <= index {
@ -268,7 +337,7 @@ impl<'a> AttrsList<'a> {
// New span has index..end
new.spans.push((
0..self.spans[i].0.end - index,
self.spans[i].1
self.spans[i].1.clone()
));
// Old span has start..index
self.spans[i].0.end = index;