Skip to content

Commit

Permalink
#72 pass relay recursively
Browse files Browse the repository at this point in the history
  • Loading branch information
yegor256 committed Jan 11, 2023
1 parent 943ceba commit 311d7dc
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 11 deletions.
23 changes: 19 additions & 4 deletions src/find.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@ impl Relay for DeadRelay {
}
}

impl DeadRelay {
/// Make a new one, the empty one.
pub fn new() -> Self {
DeadRelay {}
}
}

impl Default for DeadRelay {
/// The default dead relay.
#[allow(dead_code)]
fn default() -> Self {
Self::new()
}
}

impl LambdaRelay {
/// Makes a new instance of `LambdaRelay` with the encapsulated
/// function.
Expand Down Expand Up @@ -68,7 +83,7 @@ impl Sodg {
///
/// If target vertex is not found or `v1` is absent,
/// an `Err` will be returned.
pub fn find<T: Relay>(&self, v1: u32, loc: &str, relay: T) -> Result<u32> {
pub fn find<T: Relay + Copy>(&self, v1: u32, loc: &str, relay: T) -> Result<u32> {
let mut v = v1;
let mut locator: VecDeque<String> = VecDeque::new();
loc.split('.')
Expand Down Expand Up @@ -98,7 +113,7 @@ impl Sodg {
let (head, tail) = Self::split_a(&k);
let redirect = relay.re(v, &head, &tail);
let failure = if let Ok(re) = redirect {
if let Ok(to) = self.find(v, re.as_str(), DeadRelay {}) {
if let Ok(to) = self.find(v, re.as_str(), relay) {
trace!("#find_with_closure: ν{v}.{k} -> ν{to} (redirect to .{re})");
v = to;
continue;
Expand Down Expand Up @@ -162,7 +177,7 @@ fn finds_with_closure() -> Result<()> {
fn finds_root() -> Result<()> {
let mut g = Sodg::empty();
g.add(0)?;
assert_eq!(0, g.find(0, "", DeadRelay {})?);
assert_eq!(0, g.find(0, "", DeadRelay::default())?);
Ok(())
}

Expand All @@ -172,7 +187,7 @@ fn closure_return_absolute_vertex() {
g.add(0).unwrap();
g.add(1).unwrap();
g.bind(0, 1, "foo").unwrap();
assert!(g.find(0, "bar", DeadRelay {}).is_err());
assert!(g.find(0, "bar", DeadRelay::new()).is_err());
let v = g
.find(
0,
Expand Down
17 changes: 10 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,24 +94,27 @@ pub struct Sodg {
alerts_active: bool,
}

/// A relay that is used with `Sodg::find()` can't find an attribute.
/// It asks the relay for the name of the attribute to use instead
/// of the not found one, which is provided in the `a` parameter. The
/// `v` parameter is the ID of the vertex where the attribute `a` is not
/// found. The `b` is the locator of the attribute.
/// A relay that is used by [`Sodg::find()`] when it can't find an attribute.
/// The finding algorithm asks the relay for the name of the attribute to use instead
/// of the not found one, which is provided as the `a` argument to the relay. The
/// `v` argument provided to the relay is the ID of the vertex
/// where the attribute `a` is not found. The `b` argument
/// is the locator of the not found attribute.
///
/// A relay may return a new vertex ID as a string `"ν42"`, for example.
/// Pretty much anything that the relay will return will be used
/// Pretty much anything that the relay returns will be used
/// as a new search string, starting from the `v` vertex.
pub trait Relay {
fn re(&self, v: u32, a: &str, b: &str) -> Result<String>;
}

/// This `Relay` doesn't even try to find anything, but returns
/// an error.
/// an error. If you don't know what relay to use, use [`DeadRelay::new()`].
#[derive(Clone, Copy)]
pub struct DeadRelay {}

/// This `Relay` can be made of a lambda function.
#[derive(Clone, Copy)]
pub struct LambdaRelay {
lambda: fn(u32, &str, &str) -> Result<String>,
}
Expand Down

0 comments on commit 311d7dc

Please sign in to comment.