Skip to main content

Crate golink

Crate golink 

Source
Expand description

The Golink crate is an engine for resolving URLs for link shortening services. You provide a link to expand and a function for mapping short URLs to long URLs, and this crate will:

  • Normalize your input to ignore case and hyphenation: http://go/My-Service and http://go/myservice are treated as the same input into your mapping function

  • Append secondary paths to your resolved URL: if your mapping function returns http://example.com for the given shortlink foo, then a request to http://go/foo/bar/baz will resolve to http://example.com/foo/bar/baz

  • Apply templating, when applicable: Using a simple templating language, your long URLs can powerfully place remaining path segments in your URL ad-hoc and provide a fallback value when there are no remaining path segments. For example, if your mapping function returns for the given shortlink prs the following URL:

    https://github.com/pulls?q=is:open+is:pr+review-requested:{{ if path }}{ path }{{ else }}@me{{ endif }}+archived:false

    then a request to http://go/prs returns the URL to all Github PRs to which you are assigned:

    https://github.com/pulls?q=is:open+is:pr+review-requested:@me+archived:false

    and a request to http://go/prs/jameslittle230 returns the URL to all Github PRs to which I (@jameslittle230) am assigned:

    https://github.com/pulls?q=is:open+is:pr+review-requested:jameslittle230+archived:false

This resolver performs all the functionality described in Tailscale’s Golink project

This crate doesn’t provide a web service or an interface for creating shortened links; it only provides an algorithm for resolving short URLs to long URLs.

§Usage

The Golink crate doesn’t care how you store or retrieve long URLs given a short URL; you can store them in memory, in a database, or on disk, as long as they are retrievable from within a closure you pass into the resolve() or resolve_async() function.

§Synchronous API

fn lookup(input: &str) -> Option<String> {
    if input == "foo" {
        return Some("http://example.com".to_string());
    }
    None
}

let resolved = golink::resolve("/foo", &lookup);
 //         or golink::resolve("foo", &lookup);
 //         or golink::resolve("https://example.com/foo", &lookup);

match resolved {
   Ok(golink::GolinkResolution::RedirectRequest { url, shortlink }) => {
       // Redirect to `url`
       // If you collect analytics, then increment the click count for `shortlink`
   }

   Ok(golink::GolinkResolution::MetadataRequest(key)) => {
       // `key` is the original shortlink.
       // Return JSON that displays metadata/analytics about `key`
   }

   Err(e) => {
       // Return an error to the user based on the type of error (see `GolinkError` for more)
   }
}

§Asynchronous API

For async contexts (e.g., database lookups), use resolve_async():

let resolved = golink::resolve_async("/foo", |input| {
    let input = input.to_string();
    async move {
        // Could be an async database query
        if input == "foo" {
            return Some("http://example.com".to_string());
        }
        None
    }
}).await;

match resolved {
   Ok(golink::GolinkResolution::RedirectRequest { url, shortlink }) => {
       // Redirect to `url`
       // Optionally use `shortlink` for analytics
   }
   Ok(golink::GolinkResolution::MetadataRequest(key)) => {
       // Return metadata about `key`
   }
   Err(e) => {
       // Handle error
   }
}

Enums§

GolinkError
Errors that can occur during shortlink resolution.
GolinkResolution
The result of resolving a short URL.

Functions§

normalize_shortlink
Normalizes a shortlink by extracting the first path segment and converting to lowercase, removing hyphens and spaces.
resolve
Resolves a short URL to its expanded form using the provided synchronous lookup function.
resolve_async
Resolves a short URL to its expanded form using the provided asynchronous lookup function.