Merging an overlapping collection of intervals I'm getting myself acquainted with Rust and decided to implement the classical overlapping intervals problem. 

Here is a statement of the problem:


  Given a collection of intervals, write a function that merges all
  overlapping intervals and prints them out.
  
  For example, given [1, 3], [2, 6], [8, 10], and [7, 11], the function
  should print [1, 6], [7, 11]. Or given [5, 12], and [8, 10] the
  function should print [5, 12].
  
  You can assume that the first element of each interval is always less
  or equal than the second element of the interval.


This is my implementation:

use std::cmp;
use std::fmt::Write;

//--------------- Range ---------------//

#[derive(Copy, Clone)]
struct Range{
    start: i32,
    end: i32,
}

fn new_range(start: i32, end: i32)-&gt;Range{
    Range{
        start: start,
        end: end,
    }
}

impl Range{
    fn overlaps(&amp;self,other: &amp;Range) -&gt; bool{
        (other.start &gt;= self.start &amp;&amp; other.start &lt;= self.end)
        || (other.end &gt;= self.start &amp;&amp; other.end &lt;= self.end)
    }

    fn merge(&amp;mut self, other: &amp;Range){
        self.start = cmp::min(self.start, other.start);
        self.end = cmp::max(self.end, other.end);
    }

    fn to_string(&amp;self)-&gt;String{
        format!("[{},{}]",self.start,self.end)
    }
}

//--------------- RangeStack ----------------//

struct RangeStack{
    ranges: Vec&lt;Range&gt;,
}

fn range_stack_with_ranges(ranges : &amp;Vec&lt;Range&gt;)-&gt;RangeStack{
    let mut raw_ranges = ranges.to_vec();
    raw_ranges.sort_by(|a,b| a.start.cmp(&amp;b.start));

    let mut range_stack = RangeStack{
        ranges: Vec::new(),
    };

    for range in raw_ranges.iter(){
        range_stack.add(range);
    }

    range_stack
}

impl RangeStack{

    //private
    fn add(&amp;mut self,range :&amp;Range){
        if self.ranges.len() == 0 {
            self.ranges.push(range.clone());
        }else if self.ranges.last_mut().unwrap().overlaps(range){
                self.ranges.last_mut().unwrap().merge(range);
        }else{
                self.ranges.push(range.clone());
        }
    }

    fn to_string(&amp;self) -&gt; String {

        let mut res = String::new();
        for range in self.ranges.iter() {
            write!(&amp;mut res, "{}", range.to_string()).unwrap();
        }

        res
    }
}

//--------------- Main ---------------//

fn main() {
    let v = vec![
        new_range(3,6),
        new_range(1,5),
        new_range(7,11),
        new_range(9,12),
        new_range(4,8),
    ];

    let rs = range_stack_with_ranges(&amp;v);
    print!("Result: {}\n",rs.to_string());
}


I would appreciate it if someone could review the Rust code and let me know if there is anything that is not idiomatic. In particular, I'm not sure if my usage of mut would be considered ideal.
Some style issues:


Space before {
Spaces around -&gt;
Space after ,
No space before :
Space before else
Indent else blocks 4 characters


Make constructor functions part of the impl:

impl Range {
    fn new(start: i32, end: i32) -&gt; Range {
        Range {
            start: start,
            end: end,
        }
    }
}


Instead of creating a to_string method, implement Display instead. This allows you to automatically get .to_string(), but even better, means you can format the object without extraneous allocation: 

impl fmt::Display for Range {
    fn fmt(&amp;self, f: &amp;mut fmt::Formatter) -&gt; fmt::Result {
        write!(f, "[{},{}]", self.start, self.end)
    }
}


No need to use iter() when using a for loop on a slice or Vec, just take a reference:

for range in &amp;self.ranges { ... }


Use pattern matching to avoid all the unwrap calls in RangeStack::add:

fn add(&amp;mut self, range: &amp;Range) {
    if let Some(last) = self.ranges.last_mut() {
        if last.overlaps(range) {
            last.merge(range);
            return;
        }
    }

    self.ranges.push(range.clone());
}


Never take a &amp;Vec&lt;T&gt; as an argument. It needlessly limits what types you can accept. In your case, it also allows you to avoid the allocation of the vector in your main. Use a slice instead:

fn with_ranges(ranges: &amp;[Range]) -&gt; RangeStack { ... }


You probably always want to implement Debug, usually done via derive:

#[derive(Debug, Copy, Clone)]
struct Range { ... }


Consider making your with_ranges constructor more generic by implementing FromIterator:

impl FromIterator&lt;Range&gt; for RangeStack {
    fn from_iter&lt;I&gt;(iterator: I) -&gt; Self
        where I: IntoIterator&lt;Item=Range&gt;
    {
        let mut raw_ranges: Vec&lt;_&gt; = iterator.into_iter().collect();
        // ...
    }
}


All together, this now looks like

use std::{cmp, fmt};
use std::iter::FromIterator;

#[derive(Debug, Copy, Clone)]
struct Range {
    start: i32,
    end: i32,
}

impl Range {
    fn new(start: i32, end: i32) -&gt; Range {
        Range {
            start: start,
            end: end,
        }
    }

    fn overlaps(&amp;self, other: &amp;Range) -&gt; bool {
        (other.start &gt;= self.start &amp;&amp; other.start &lt;= self.end)
        || (other.end &gt;= self.start &amp;&amp; other.end &lt;= self.end)
    }

    fn merge(&amp;mut self, other: &amp;Range) {
        self.start = cmp::min(self.start, other.start);
        self.end = cmp::max(self.end, other.end);
    }
}

impl fmt::Display for Range {
    fn fmt(&amp;self, f: &amp;mut fmt::Formatter) -&gt; fmt::Result {
        write!(f, "[{},{}]", self.start, self.end)
    }
}

#[derive(Debug, Clone)]
struct RangeStack {
    ranges: Vec&lt;Range&gt;,
}

impl RangeStack {
    fn add(&amp;mut self, range: &amp;Range) {
        if let Some(last) = self.ranges.last_mut() {
            if last.overlaps(range) {
                last.merge(range);
                return;
            }
        }

        self.ranges.push(*range);
    }
}

impl fmt::Display for RangeStack {
    fn fmt(&amp;self, f: &amp;mut fmt::Formatter) -&gt; fmt::Result {
        for range in &amp;self.ranges {
            try!(write!(f, " {}", range));
        }
        Ok(())
    }
}

impl FromIterator&lt;Range&gt; for RangeStack {
    fn from_iter&lt;I&gt;(iterator: I) -&gt; Self
        where I: IntoIterator&lt;Item=Range&gt;
    {
        let mut raw_ranges: Vec&lt;_&gt; = iterator.into_iter().collect();
        raw_ranges.sort_by(|a,b| a.start.cmp(&amp;b.start));

        let mut range_stack = RangeStack {
            ranges: Vec::new(),
        };

        for range in &amp;raw_ranges {
            range_stack.add(range);
        }

        range_stack
    }
}

impl&lt;'a&gt; FromIterator&lt;&amp;'a Range&gt; for RangeStack {
    fn from_iter&lt;I&gt;(iterator: I) -&gt; Self
        where I: IntoIterator&lt;Item=&amp;'a Range&gt;
    {
        iterator.into_iter().cloned().collect()
    }
}

fn main() {
    let v = [
        Range::new(3, 6),
        Range::new(1, 5),
        Range::new(7, 11),
        Range::new(9, 12),
        Range::new(4, 8),
    ];

    let rs: RangeStack = v.iter().collect();
    print!("Result: {}\n", rs);
}