Skip to content

Commit 8b16d1f

Browse files
committed
auto merge of #19252 : japaric/rust/cow, r=aturon
- Add `IntoCow` trait, and put it in the prelude - Add `is_owned`/`is_borrowed` methods to `Cow` - Add `CowString`/`CowVec` type aliases (to `Cow<'_, String, str>`/`Cow<'_, Vec, [T]>` respectively) - `Cow` implements: `Show`, `Hash`, `[Partial]{Eq,Ord}` - `impl BorrowFrom<Cow<'a, T, B>> for B` [breaking-change]s: - `IntoMaybeOwned` has been removed from the prelude - libcollections: `SendStr` is now an alias to `CowString<'static>` (it was aliased to `MaybeOwned<'static>`) - libgraphviz: - `LabelText` variants now wrap `CowString` instead of `MaybeOwned` - `Nodes` and `Edges` are now type aliases to `CowVec` (they were aliased to `MaybeOwnedVec`) - libstd/path: `Display::as_maybe_owned` has been renamed to `Display::as_cow` and now returns a `CowString` - These functions now accept/return `Cow` instead of `MaybeOwned[Vector]`: - libregex: `Replacer::reg_replace` - libcollections: `str::from_utf8_lossy` - libgraphviz: `Id::new`, `Id::name`, `LabelText::pre_escaped_content` - libstd: `TaskBuilder::named` r? @aturon
2 parents c069714 + 616f1f1 commit 8b16d1f

File tree

2 files changed

+40
-33
lines changed

2 files changed

+40
-33
lines changed

lib.rs

+30-33
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pairs of ints, representing the edges (the node set is implicit).
3737
Each node label is derived directly from the int representing the node,
3838
while the edge labels are all empty strings.
3939
40-
This example also illustrates how to use `MaybeOwnedVector` to return
40+
This example also illustrates how to use `CowVec` to return
4141
an owned vector or a borrowed slice as appropriate: we construct the
4242
node vector from scratch, but borrow the edge list (rather than
4343
constructing a copy of all the edges from scratch).
@@ -48,7 +48,6 @@ which is cyclic.
4848
4949
```rust
5050
use graphviz as dot;
51-
use graphviz::maybe_owned_vec::IntoMaybeOwnedVector;
5251
5352
type Nd = int;
5453
type Ed = (int,int);
@@ -77,12 +76,12 @@ impl<'a> dot::GraphWalk<'a, Nd, Ed> for Edges {
7776
}
7877
nodes.sort();
7978
nodes.dedup();
80-
nodes.into_maybe_owned()
79+
nodes.into_cow()
8180
}
8281
8382
fn edges(&'a self) -> dot::Edges<'a,Ed> {
8483
let &Edges(ref edges) = self;
85-
edges.as_slice().into_maybe_owned()
84+
edges.as_slice().into_cow()
8685
}
8786
8887
fn source(&self, e: &Ed) -> Nd { let &(s,_) = e; s }
@@ -137,8 +136,8 @@ edges stored in `self`.
137136
Since both the set of nodes and the set of edges are always
138137
constructed from scratch via iterators, we use the `collect()` method
139138
from the `Iterator` trait to collect the nodes and edges into freshly
140-
constructed growable `Vec` values (rather use the `into_maybe_owned`
141-
from the `IntoMaybeOwnedVector` trait as was used in the first example
139+
constructed growable `Vec` values (rather use the `into_cow`
140+
from the `IntoCow` trait as was used in the first example
142141
above).
143142
144143
The output from this example renders four nodes that make up the
@@ -148,7 +147,6 @@ entity `&sube`).
148147
149148
```rust
150149
use graphviz as dot;
151-
use std::str;
152150
153151
type Nd = uint;
154152
type Ed<'a> = &'a (uint, uint);
@@ -168,10 +166,10 @@ impl<'a> dot::Labeller<'a, Nd, Ed<'a>> for Graph {
168166
dot::Id::new(format!("N{}", n)).unwrap()
169167
}
170168
fn node_label<'a>(&'a self, n: &Nd) -> dot::LabelText<'a> {
171-
dot::LabelStr(str::Slice(self.nodes[*n].as_slice()))
169+
dot::LabelStr(self.nodes[*n].as_slice().into_cow())
172170
}
173171
fn edge_label<'a>(&'a self, _: &Ed) -> dot::LabelText<'a> {
174-
dot::LabelStr(str::Slice("&sube;"))
172+
dot::LabelStr("&sube;".into_cow())
175173
}
176174
}
177175
@@ -204,7 +202,6 @@ Hasse-diagram for the subsets of the set `{x, y}`.
204202
205203
```rust
206204
use graphviz as dot;
207-
use std::str;
208205
209206
type Nd<'a> = (uint, &'a str);
210207
type Ed<'a> = (Nd<'a>, Nd<'a>);
@@ -225,10 +222,10 @@ impl<'a> dot::Labeller<'a, Nd<'a>, Ed<'a>> for Graph {
225222
}
226223
fn node_label<'a>(&'a self, n: &Nd<'a>) -> dot::LabelText<'a> {
227224
let &(i, _) = n;
228-
dot::LabelStr(str::Slice(self.nodes[i].as_slice()))
225+
dot::LabelStr(self.nodes[i].as_slice().into_cow())
229226
}
230227
fn edge_label<'a>(&'a self, _: &Ed<'a>) -> dot::LabelText<'a> {
231-
dot::LabelStr(str::Slice("&sube;"))
228+
dot::LabelStr("&sube;".into_cow())
232229
}
233230
}
234231
@@ -279,8 +276,8 @@ pub fn main() {
279276
pub use self::LabelText::*;
280277

281278
use std::io;
282-
use std::str;
283-
use self::maybe_owned_vec::MaybeOwnedVector;
279+
use std::str::CowString;
280+
use std::vec::CowVec;
284281

285282
pub mod maybe_owned_vec;
286283

@@ -290,7 +287,7 @@ pub enum LabelText<'a> {
290287
///
291288
/// Occurrences of backslashes (`\`) are escaped, and thus appear
292289
/// as backslashes in the rendered label.
293-
LabelStr(str::MaybeOwned<'a>),
290+
LabelStr(CowString<'a>),
294291

295292
/// This kind of label uses the graphviz label escString type:
296293
/// http://www.graphviz.org/content/attrs#kescString
@@ -302,7 +299,7 @@ pub enum LabelText<'a> {
302299
/// to break a line (centering the line preceding the `\n`), there
303300
/// are also the escape sequences `\l` which left-justifies the
304301
/// preceding line and `\r` which right-justifies it.
305-
EscStr(str::MaybeOwned<'a>),
302+
EscStr(CowString<'a>),
306303
}
307304

308305
// There is a tension in the design of the labelling API.
@@ -339,7 +336,7 @@ pub enum LabelText<'a> {
339336

340337
/// `Id` is a Graphviz `ID`.
341338
pub struct Id<'a> {
342-
name: str::MaybeOwned<'a>,
339+
name: CowString<'a>,
343340
}
344341

345342
impl<'a> Id<'a> {
@@ -357,10 +354,10 @@ impl<'a> Id<'a> {
357354
///
358355
/// Passing an invalid string (containing spaces, brackets,
359356
/// quotes, ...) will return an empty `Err` value.
360-
pub fn new<Name:str::IntoMaybeOwned<'a>>(name: Name) -> Result<Id<'a>, ()> {
361-
let name = name.into_maybe_owned();
357+
pub fn new<Name: IntoCow<'a, String, str>>(name: Name) -> Result<Id<'a>, ()> {
358+
let name = name.into_cow();
362359
{
363-
let mut chars = name.as_slice().chars();
360+
let mut chars = name.chars();
364361
match chars.next() {
365362
Some(c) if is_letter_or_underscore(c) => { ; },
366363
_ => return Err(())
@@ -383,10 +380,10 @@ impl<'a> Id<'a> {
383380
}
384381

385382
pub fn as_slice(&'a self) -> &'a str {
386-
self.name.as_slice()
383+
&*self.name
387384
}
388385

389-
pub fn name(self) -> str::MaybeOwned<'a> {
386+
pub fn name(self) -> CowString<'a> {
390387
self.name
391388
}
392389
}
@@ -421,7 +418,7 @@ pub trait Labeller<'a,N,E> {
421418
/// default is in fact the empty string.
422419
fn edge_label(&'a self, e: &E) -> LabelText<'a> {
423420
let _ignored = e;
424-
LabelStr(str::Slice(""))
421+
LabelStr("".into_cow())
425422
}
426423
}
427424

@@ -454,11 +451,11 @@ impl<'a> LabelText<'a> {
454451
/// yields same content as self. The result obeys the law
455452
/// render(`lt`) == render(`EscStr(lt.pre_escaped_content())`) for
456453
/// all `lt: LabelText`.
457-
fn pre_escaped_content(self) -> str::MaybeOwned<'a> {
454+
fn pre_escaped_content(self) -> CowString<'a> {
458455
match self {
459456
EscStr(s) => s,
460-
LabelStr(s) => if s.as_slice().contains_char('\\') {
461-
str::Owned(s.as_slice().escape_default())
457+
LabelStr(s) => if s.contains_char('\\') {
458+
s.escape_default().into_cow()
462459
} else {
463460
s
464461
},
@@ -476,12 +473,12 @@ impl<'a> LabelText<'a> {
476473
let suffix = suffix.pre_escaped_content();
477474
prefix.push_str(r"\n\n");
478475
prefix.push_str(suffix.as_slice());
479-
EscStr(str::Owned(prefix))
476+
EscStr(prefix.into_cow())
480477
}
481478
}
482479

483-
pub type Nodes<'a,N> = MaybeOwnedVector<'a,N>;
484-
pub type Edges<'a,E> = MaybeOwnedVector<'a,E>;
480+
pub type Nodes<'a,N> = CowVec<'a,N>;
481+
pub type Edges<'a,E> = CowVec<'a,E>;
485482

486483
// (The type parameters in GraphWalk should be associated items,
487484
// when/if Rust supports such.)
@@ -496,7 +493,7 @@ pub type Edges<'a,E> = MaybeOwnedVector<'a,E>;
496493
/// that is bound by the self lifetime `'a`.
497494
///
498495
/// The `nodes` and `edges` method each return instantiations of
499-
/// `MaybeOwnedVector` to leave implementers the freedom to create
496+
/// `CowVec` to leave implementers the freedom to create
500497
/// entirely new vectors or to pass back slices into internally owned
501498
/// vectors.
502499
pub trait GraphWalk<'a, N, E> {
@@ -512,7 +509,7 @@ pub trait GraphWalk<'a, N, E> {
512509

513510
/// Renders directed graph `g` into the writer `w` in DOT syntax.
514511
/// (Main entry point for the library.)
515-
pub fn render<'a, N:'a, E:'a, G:Labeller<'a,N,E>+GraphWalk<'a,N,E>, W:Writer>(
512+
pub fn render<'a, N:Clone+'a, E:Clone+'a, G:Labeller<'a,N,E>+GraphWalk<'a,N,E>, W:Writer>(
516513
g: &'a G,
517514
w: &mut W) -> io::IoResult<()>
518515
{
@@ -647,12 +644,12 @@ mod tests {
647644
}
648645
fn node_label(&'a self, n: &Node) -> LabelText<'a> {
649646
match self.node_labels[*n] {
650-
Some(ref l) => LabelStr(str::Slice(l.as_slice())),
647+
Some(ref l) => LabelStr(l.into_cow()),
651648
None => LabelStr(id_name(n).name()),
652649
}
653650
}
654651
fn edge_label(&'a self, e: & &'a Edge) -> LabelText<'a> {
655-
LabelStr(str::Slice(e.label.as_slice()))
652+
LabelStr(e.label.into_cow())
656653
}
657654
}
658655

maybe_owned_vec.rs

+10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![deprecated = "use std::vec::CowVec"]
12+
1113
pub use self::MaybeOwnedVector::*;
1214

1315
use std::default::Default;
@@ -46,12 +48,16 @@ pub trait IntoMaybeOwnedVector<'a,T> {
4648
fn into_maybe_owned(self) -> MaybeOwnedVector<'a,T>;
4749
}
4850

51+
#[allow(deprecated)]
4952
impl<'a,T:'a> IntoMaybeOwnedVector<'a,T> for Vec<T> {
53+
#[allow(deprecated)]
5054
#[inline]
5155
fn into_maybe_owned(self) -> MaybeOwnedVector<'a,T> { Growable(self) }
5256
}
5357

58+
#[allow(deprecated)]
5459
impl<'a,T> IntoMaybeOwnedVector<'a,T> for &'a [T] {
60+
#[allow(deprecated)]
5561
#[inline]
5662
fn into_maybe_owned(self) -> MaybeOwnedVector<'a,T> { Borrowed(self) }
5763
}
@@ -66,6 +72,7 @@ impl<'a,T> MaybeOwnedVector<'a,T> {
6672

6773
pub fn len(&self) -> uint { self.as_slice().len() }
6874

75+
#[allow(deprecated)]
6976
pub fn is_empty(&self) -> bool { self.len() == 0 }
7077
}
7178

@@ -114,6 +121,7 @@ impl<'b,T> AsSlice<T> for MaybeOwnedVector<'b,T> {
114121
}
115122

116123
impl<'a,T> FromIterator<T> for MaybeOwnedVector<'a,T> {
124+
#[allow(deprecated)]
117125
fn from_iter<I:Iterator<T>>(iterator: I) -> MaybeOwnedVector<'a,T> {
118126
// If we are building from scratch, might as well build the
119127
// most flexible variant.
@@ -143,6 +151,7 @@ impl<'a,T:Clone> CloneSliceAllocPrelude<T> for MaybeOwnedVector<'a,T> {
143151
}
144152

145153
impl<'a, T: Clone> Clone for MaybeOwnedVector<'a, T> {
154+
#[allow(deprecated)]
146155
fn clone(&self) -> MaybeOwnedVector<'a, T> {
147156
match *self {
148157
Growable(ref v) => Growable(v.clone()),
@@ -152,6 +161,7 @@ impl<'a, T: Clone> Clone for MaybeOwnedVector<'a, T> {
152161
}
153162

154163
impl<'a, T> Default for MaybeOwnedVector<'a, T> {
164+
#[allow(deprecated)]
155165
fn default() -> MaybeOwnedVector<'a, T> {
156166
Growable(Vec::new())
157167
}

0 commit comments

Comments
 (0)