Using a custom comparison function for BTreeSet and a foreign type
Your code looks basically how I would write it, very nice! I do have a few tiny nits.


I strongly dislike using Deref except when you have a smart pointer. I fear that using Deref to compose items is going to be the Rust equivalent of using inheritance for code reuse.

Using Deref also can be a bit surprising, as every method is now available. Let's say that your Data struct has some more methods:

impl Data {
    fn wow(&amp;self) { println!("Wow") }
}


Now, your SortableData has those methods as well!

for d in sorted.iter() {
    d.wow();
}


I much prefer to be explicit about it; I would implement Borrow instead.

I don't believe this opinion to be 100% supported by the community, but I'm going to make my case where I can ^_^
When possible, I'd implement From / Into in both directions. This doesn't always make sense, but here it does.
There's no need to specify the type for source — type inference handles that just fine.
You could just map the into function directly: .map(Into::into).
Instead of calling iter in the for loop expression, you can just take a reference.
From and Into are both part of the prelude and thus don't need to be used again.




use std::borrow::Borrow;
use std::cmp::Ordering;
use std::collections::BTreeSet;

// Here's the original struct...
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
struct Data(usize);

impl From&lt;usize&gt; for Data {
    fn from(i: usize) -&gt; Self {
        Data(i)
    }
}

// And here's the wrapper type we'll use to sort it.
#[derive(PartialEq, Eq, Debug)]
struct SortableData(Data);

impl From&lt;Data&gt; for SortableData {
    fn from(data: Data) -&gt; Self {
        SortableData(data)
    }
}

impl From&lt;SortableData&gt; for Data {
    fn from(data: SortableData) -&gt; Self {
        data.0
    }
}

impl Borrow&lt;Data&gt; for SortableData {
    fn borrow(&amp;self) -&gt; &amp;Data {
        &amp;self.0
    }
}

impl PartialOrd for SortableData {
    fn partial_cmp(&amp;self, other: &amp;Self) -&gt; Option&lt;Ordering&gt; {
        Some(self.cmp(other))
    }
}

impl Ord for SortableData {
    fn cmp(&amp;self, other: &amp;Self) -&gt; Ordering {
        (self.0).0.cmp(&amp;(other.0).0)
    }
}

fn main() {
    let source = [Data(9), Data(4), Data(2)];
    let sorted: BTreeSet&lt;SortableData&gt; = source.iter().cloned().map(Into::into).collect();
    for d in &amp;sorted {
        let d: &amp;Data = d.borrow();
        println!("{:?}", d);
    }
}