Skip to content
This repository has been archived by the owner on Feb 3, 2023. It is now read-only.

Adds regex matching for link tags and types #1453

Merged
merged 14 commits into from
Jun 11, 2019
Merged

Adds regex matching for link tags and types #1453

merged 14 commits into from
Jun 11, 2019

Conversation

willemolding
Copy link
Collaborator

@willemolding willemolding commented May 30, 2019

PR summary

get_links now accepts an enum for the tag and type which has the following form:

pub enum LinkMatch<S: Into<String>> {
    Any,
    Exactly(S),
    Regex(S),
}

This makes the link calls nice and self descriptive e.g.

get_links(
    .... 
    LinkMatch::Exactly("type-name"), 
    LinkMatch::Any
)

This has also made the implementation significantly simpler as all of the variants are converted to their regex form in the HDK before being ingested by core. Previously the Option type was kept and mapped to a reserved char (*) for transporting over the network.

Also adds an apps spec test.

changelog

Please check one of the following, relating to the CHANGELOG-UNRELEASED.md

  • this is a code change that effects some consumer (e.g. zome developers) of holochain core so it is added to the CHANGELOG-UNRELEASED.md (linked above), with the format - summary of change [PR#1234](https://github.com/holochain/holochain-rust/pull/1234)
  • this is not a code change, or doesn't effect anyone outside holochain core development

@@ -62,16 +63,20 @@ impl DhtStore {
link_type: Option<String>,
tag: Option<String>,
) -> Result<BTreeSet<EntityAttributeValueIndex>, HolochainError> {
// interpret link tags and types as regex
let link_type = link_type.map(|s| Regex::new(&s).unwrap());
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should improve handling of invalid regex and ensure the error happens in the calling code

@willemolding willemolding requested review from lucksus, zippy and thedavidmeister and removed request for lucksus and zippy May 30, 2019 06:14
@pdaoust
Copy link
Collaborator

pdaoust commented May 30, 2019

It's really exciting to see this being explored already! I'm just chewing on it from a zome developer's perspective...

I feel like having it as a string field that always gets interpreted as a regex puts a burden on the developer to remember to put start/end anchors on and escape special chars when they want an exact tag match. I don't know if there's an idiomatic Rust way of specifying either string or regex, but I feel like there must be. In lieu of that, how about something like

enum LinksTagQuery {
    Any,
    ExactMatch(String),
    RegexMatch(Regex)
}

// default case -- assume exact match when a string is given
impl From<String> for LinksTagQuery {
    fn from(match: String) -> Self {
        LinksTagQuery::ExactMatch(match)
    }
}

// this is where you get to be explicit about regexes
impl From<Regex> for LinksTagQuery
    fn from(match: Regex) -> Self {
        LinksTagQuery::RegexMatch(match)
    }
}

I don't know if that Any is un-idiomatic, and whether it'd be better to use an Option<LinksTagQuery> -- feel like if we use an enum anyway, the intention of Any is clearer. The other reason I like Any is that, while you could use /.*/, people have this picture of regexes 'feeling' expensive and would probably appreciate a way of knowing that the underlying implementation isn't trying to parse and execute a regex against every link tag. (This is possible with Option too of course, though with less explicit semantics.) I know you shouldn't have to think about how leaky the abstraction is, but let's be honest: devs will end up doing it anyway.

It also opens the door to different query types in the future, although that's getting into YAGNI territory.

@pdaoust
Copy link
Collaborator

pdaoust commented May 30, 2019

Oh, also, do we want to be able to do regex matching on link_type? I feel like it should be made homeomorphic with the entry_type_names param from hdk::query so devs have to remember fewer gotchas -- heck, maybe they should all become regexes or the above type of enum; I dunno!

@willemolding
Copy link
Collaborator Author

Oh, also, do we want to be able to do regex matching on link_type? I feel like it should be made homeomorphic with the entry_type_names param from hdk::query so devs have to remember fewer gotchas -- heck, maybe they should all become regexes or the above type of enum; I dunno!

Oh yeah it is for both. The PR name just refers to the tag.

I think the enum approach is a great way to go. I think I will map them all into stringified regex immediately in the HDK and then it is uniform after that.

@pdaoust
Copy link
Collaborator

pdaoust commented May 30, 2019

I think I will map them all into stringified regex immediately in the HDK and then it is uniform after that.

oh, well if you do that, then I guess there isn't really any reason for LinksTagQuery::RegexMatch to take a Regex at all -- just make it take a string too, get devs to be explicit about what they want, and don't bother with the From implementations. Is there any performance cost to treating exact matches as regexes?

@willemolding
Copy link
Collaborator Author

So I'm thinking we have some cleverly named enums so it looks like:

hdk::get_links(
    base,
    LinkTypeMatch::Any,
    LinkTagMatch::Exactly("tag1")
)

and also `LinkTagMatch::Regex("^[1-9]*")` or whatever. Its like a little DSL. This will all get mapped straight to a regex in the HDK and holochain core will only know about the regex form.

@pdaoust
Copy link
Collaborator

pdaoust commented Jun 3, 2019

@willemolding this is looking beautiful. I'm all for DSLs, and Rust enums appear to make it super easy. Should be trivial to then implement LinkTypeMatch::Glob("**/blah")... in fact, why not just implement a TypeMatch enum and make aliases for EntryTypeMatch, LinkTypeMatch, and LinkTagMatch? That way, devs wouldn't have to think about what type/tag matches are usable in which query. (I'm all for API symmetry for improved developer experience... ever had the displeasure of writing in PHP? ;) )

@willemolding
Copy link
Collaborator Author

willemolding commented Jun 4, 2019

Ok I was able to implement it almost exactly as we specified. The only thing is type aliases for enums are experimental apparently so I just have one type for both the type and tag fields.

This has also simplified some of the underlying implementation significantly.

@willemolding willemolding changed the title spike? - adds regex matching an an app spec test Adds regex matching for link tags and types Jun 4, 2019
@willemolding willemolding requested a review from maackle June 4, 2019 06:26
Copy link
Collaborator

@pdaoust pdaoust left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh crap! just realised I started a review and left it open. I didn't want to make this change directly, on account of not knowing much about Rust yet 😬

core_types/src/link/mod.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@StaticallyTypedAnxiety StaticallyTypedAnxiety left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

@pdaoust
Copy link
Collaborator

pdaoust commented Jun 10, 2019

Looks good to me too. I'll expand on how breaking the change is in the Dev Pulse -- logically it hasn't changed (much) but the addition of the new enum will require people to start using it.

Thanks @pdaoust I didn't consider that tags could be weird regexes when the caller has no intention of them being treated as such.

Never underestimate the power of a third-party developer to break your things ;)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants