Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# <future version>

### Added
- Add support for associated constants

### Changed
- updated the crate to rust 2018 edition

Expand Down
17 changes: 17 additions & 0 deletions src/associated_const.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use crate::bound::Bound;
use crate::r#type::Type;

/// Defines an associated constant.
#[derive(Debug, Clone)]
pub struct AssociatedConst(pub Bound);

impl AssociatedConst {
/// Set the bound on the associated constant.
pub fn bound<T>(&mut self, ty: T) -> &mut Self
where
T: Into<Type>,
{
self.0.bound = vec![ty.into()];
self
}
}
4 changes: 4 additions & 0 deletions src/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ pub struct Field {

/// Field annotation
pub annotation: Vec<String>,

/// Field value
pub value: String,
}

impl Field {
Expand All @@ -27,6 +30,7 @@ impl Field {
ty: ty.into(),
documentation: Vec::new(),
annotation: Vec::new(),
value: String::new(),
}
}

Expand Down
1 change: 1 addition & 0 deletions src/fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ impl Fields {
ty: ty.into(),
documentation: Vec::new(),
annotation: Vec::new(),
value: String::new(),
})
}

Expand Down
6 changes: 3 additions & 3 deletions src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,11 @@ impl Function {
self.args.push(Field {
name: name.to_string(),
ty: ty.into(),
// While a `Field` is used here, both `documentation`
// and `annotation` does not make sense for function arguments.
// Simply use empty strings.
// While a `Field` is used here, the following
// arguments do not make sense so use empty strings.
documentation: Vec::new(),
annotation: Vec::new(),
value: String::new(),
});

self
Expand Down
30 changes: 30 additions & 0 deletions src/impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ pub struct Impl {
/// If implementing a trait
impl_trait: Option<Type>,

/// Associated constants
assoc_csts: Vec<Field>,

/// Associated types
assoc_tys: Vec<Field>,

Expand All @@ -40,6 +43,7 @@ impl Impl {
target: target.into(),
generics: vec![],
impl_trait: None,
assoc_csts: vec![],
assoc_tys: vec![],
bounds: vec![],
fns: vec![],
Expand Down Expand Up @@ -79,6 +83,22 @@ impl Impl {
self
}

/// Set an associated constant.
pub fn associate_const<T>(&mut self, name: &str, ty: T, value: &str) -> &mut Self
where
T: Into<Type>,
{
self.assoc_csts.push(Field {
name: name.to_string(),
ty: ty.into(),
documentation: Vec::new(),
annotation: Vec::new(),
value: value.to_string(),
});

self
}

/// Set an associated type.
pub fn associate_type<T>(&mut self, name: &str, ty: T) -> &mut Self
where
Expand All @@ -89,6 +109,7 @@ impl Impl {
ty: ty.into(),
documentation: Vec::new(),
annotation: Vec::new(),
value: String::new(),
});

self
Expand Down Expand Up @@ -138,6 +159,15 @@ impl Impl {
fmt_bounds(&self.bounds, fmt)?;

fmt.block(|fmt| {
// format associated constants
if !self.assoc_csts.is_empty() {
for cst in &self.assoc_csts {
write!(fmt, "const {}: ", cst.name)?;
cst.ty.fmt(fmt)?;
write!(fmt, " = {};\n", cst.value)?;
}
}

// format associated types
if !self.assoc_tys.is_empty() {
for ty in &self.assoc_tys {
Expand Down
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
//! println!("{}", scope.to_string());
//! ```

mod associated_const;
mod associated_type;
mod block;
mod body;
Expand All @@ -47,7 +48,7 @@ mod r#struct;
mod r#trait;
mod r#type;


pub use associated_const::*;
pub use associated_type::*;
pub use block::*;
pub use field::*;
Expand Down
42 changes: 38 additions & 4 deletions src/trait.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::fmt::{self, Write};

use crate::associated_const::AssociatedConst;
use crate::associated_type::AssociatedType;
use crate::bound::Bound;
use crate::formatter::{fmt_bound_rhs, Formatter};
Expand All @@ -13,6 +14,7 @@ use crate::r#type::Type;
pub struct Trait {
type_def: TypeDef,
parents: Vec<Type>,
associated_consts: Vec<AssociatedConst>,
associated_tys: Vec<AssociatedType>,
fns: Vec<Function>,
macros: Vec<String>,
Expand All @@ -24,6 +26,7 @@ impl Trait {
Trait {
type_def: TypeDef::new(name),
parents: vec![],
associated_consts: vec![],
associated_tys: vec![],
fns: vec![],
macros: vec![],
Expand Down Expand Up @@ -77,6 +80,20 @@ impl Trait {
self
}

/// Add an associated const. Returns a mutable reference to the new
/// associated const for futher configuration.
pub fn associated_const<T>(&mut self, name: &str, ty: T) -> &mut AssociatedConst
where
T: Into<Type>,
{
self.associated_consts.push(AssociatedConst(Bound {
name: name.to_string(),
bound: vec![ty.into()],
}));

self.associated_consts.last_mut().unwrap()
}

/// Add an associated type. Returns a mutable reference to the new
/// associated type for futher configuration.
pub fn associated_type(&mut self, name: &str) -> &mut AssociatedType {
Expand Down Expand Up @@ -108,11 +125,28 @@ impl Trait {
self.type_def.fmt_head("trait", &self.parents, fmt)?;

fmt.block(|fmt| {
let assoc = &self.associated_tys;
let assoc_csts = &self.associated_consts;
let assoc_tys = &self.associated_tys;

// format associated types

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// format associated types
// format associated constants

if !assoc_csts.is_empty() {
for cst in assoc_csts {
let cst = &cst.0;

write!(fmt, "const {}", cst.name)?;

if !cst.bound.is_empty() {
write!(fmt, ": ")?;
fmt_bound_rhs(&cst.bound, fmt)?;
}

write!(fmt, ";\n")?;
}
}

// format associated types
if !assoc.is_empty() {
for ty in assoc {
if !assoc_tys.is_empty() {
for ty in assoc_tys {
let ty = &ty.0;

write!(fmt, "type {}", ty.name)?;
Expand All @@ -127,7 +161,7 @@ impl Trait {
}

for (i, func) in self.fns.iter().enumerate() {
if i != 0 || !assoc.is_empty() {
if i != 0 || !assoc_tys.is_empty() || !assoc_csts.is_empty() {
write!(fmt, "\n")?;
}

Expand Down