1
Fork 0

Moved and refactored ThinAttributes

This commit is contained in:
Marvin Löbel 2015-11-15 17:17:50 +01:00
parent 2a8f358de7
commit f0beba0217
11 changed files with 143 additions and 139 deletions

View file

@ -45,6 +45,7 @@ pub use self::ViewPath_::*;
pub use self::Visibility::*;
pub use self::PathParameters::*;
use attr::ThinAttributes;
use codemap::{Span, Spanned, DUMMY_SP, ExpnId};
use abi::Abi;
use ast_util;
@ -1952,98 +1953,6 @@ pub struct MacroDef {
pub body: Vec<TokenTree>,
}
/// A list of attributes, behind a optional box as
/// a space optimization.
pub type ThinAttributes = Option<Box<Vec<Attribute>>>;
pub trait ThinAttributesExt {
fn map_opt_attrs<F>(self, f: F) -> Self
where F: FnOnce(Vec<Attribute>) -> Vec<Attribute>;
fn prepend_outer(mut self, attrs: Self) -> Self;
fn append_inner(mut self, attrs: Self) -> Self;
fn update<F>(&mut self, f: F)
where Self: Sized,
F: FnOnce(Self) -> Self;
fn as_attrs(&self) -> &[Attribute];
fn into_attrs(self) -> Vec<Attribute>;
}
// FIXME: Rename inner/outer
// FIXME: Rename opt_attrs
impl ThinAttributesExt for ThinAttributes {
fn map_opt_attrs<F>(self, f: F) -> Self
where F: FnOnce(Vec<Attribute>) -> Vec<Attribute> {
// This is kinda complicated... Ensure the function is
// always called, and that None inputs or results are
// correctly handled.
if let Some(mut b) = self {
use std::mem::replace;
let vec = replace(&mut *b, Vec::new());
let vec = f(vec);
if vec.len() == 0 {
None
} else {
replace(&mut*b, vec);
Some(b)
}
} else {
f(Vec::new()).into_opt_attrs()
}
}
fn prepend_outer(self, attrs: ThinAttributes) -> Self {
attrs.map_opt_attrs(|mut attrs| {
attrs.extend(self.into_attrs());
attrs
})
}
fn append_inner(self, attrs: ThinAttributes) -> Self {
self.map_opt_attrs(|mut self_| {
self_.extend(attrs.into_attrs());
self_
})
}
fn update<F>(&mut self, f: F)
where Self: Sized,
F: FnOnce(ThinAttributes) -> ThinAttributes
{
let self_ = f(self.take());
*self = self_;
}
fn as_attrs(&self) -> &[Attribute] {
match *self {
Some(ref b) => b,
None => &[],
}
}
fn into_attrs(self) -> Vec<Attribute> {
match self {
Some(b) => *b,
None => Vec::new(),
}
}
}
pub trait AttributesExt {
fn into_opt_attrs(self) -> ThinAttributes;
}
impl AttributesExt for Vec<Attribute> {
fn into_opt_attrs(self) -> ThinAttributes {
if self.len() == 0 {
None
} else {
Some(Box::new(self))
}
}
}
#[cfg(test)]
mod tests {
use serialize;