-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
82d10f0
commit 1fa78ef
Showing
7 changed files
with
105 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,4 +2,5 @@ | |
members = [ | ||
"fallible_dependent_construction", | ||
"lazy_ast", | ||
"owner_with_lifetime", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[package] | ||
name = "owner_with_lifetime" | ||
version = "0.1.0" | ||
authors = ["Lukas Bergdoll <lukas.bergdoll@gmail.com>"] | ||
edition = "2018" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
self_cell = { path="../../"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# `owner_with_lifetime` Example | ||
|
||
Here we want to optionally escape an input string and then compute an AST based | ||
on this escaped string. This means we either borrow the 'input lifetime | ||
reference or the function stack local owned string produced as result of | ||
escaping the input. This can only be done with a self-referential struct, that | ||
still is statically lifetime dependent on the input. | ||
|
||
Run this example with `cargo run`, it should output: | ||
|
||
``` | ||
input: "au bx" | ||
not_escaped.borrow_dependent() -> ["au", "bx"] | ||
input: "au bz" | ||
escaping input (owned alloc) | ||
escaped.borrow_dependent() -> ["az", "bz"] | ||
``` | ||
|
||
Notice for the first input that contains an 'x' no escaping is done, so the | ||
dummy AST is a Vec of pointers into the original input. The second time with | ||
input "au bz" there is no 'x' so we need want to escape the input and build the | ||
AST based of that as seen "az" instead of "au" in the input. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// This example demonstrates a use-case where a lifetime in the owner is required. | ||
|
||
use std::borrow::Cow; | ||
|
||
use self_cell::self_cell; | ||
|
||
type Ast<'a> = Vec<&'a str>; | ||
|
||
self_cell!( | ||
struct AstCell<'input> { | ||
owner: Cow<'input, str>, | ||
|
||
#[covariant] | ||
dependent: Ast, | ||
} | ||
); | ||
|
||
impl<'input> AstCell<'input> { | ||
// Escape input if necessary before constructing AST. | ||
fn from_un_escaped(input: &'input str) -> Self { | ||
println!("input: {:?}", input); | ||
|
||
let escaped_input = if input.contains("x") { | ||
Cow::from(input) | ||
} else { | ||
println!("escaping input (owned alloc)"); | ||
let owned: String = input.replace('u', "z"); | ||
Cow::from(owned) | ||
}; | ||
|
||
// This would be impossible without a self-referential struct. | ||
// escaped_input could either be a pointer to the input or an owned | ||
// string on stack. | ||
// We only want to depend on the input lifetime and encapsulate the | ||
// string escaping logic in a function. Which we can't do with | ||
// vanilla Rust. | ||
// Non self-referential version https://godbolt.org/z/3Pcc9a5za error. | ||
Self::new(escaped_input, |escaped_input| { | ||
// Dummy for expensive computation you don't want to redo. | ||
escaped_input.split(' ').collect() | ||
}) | ||
} | ||
} | ||
|
||
fn main() { | ||
let not_escaped = AstCell::from_un_escaped("au bx"); | ||
|
||
println!( | ||
"not_escaped.borrow_dependent() -> {:?}", | ||
not_escaped.borrow_dependent() | ||
); | ||
|
||
let escaped = AstCell::from_un_escaped("au bz"); | ||
|
||
println!( | ||
"escaped.borrow_dependent() -> {:?}", | ||
escaped.borrow_dependent() | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters