Go to file
Luis Lavena 2e77e6463a Switch dev tooling to containers
Move away from local installed Crystal and use `hydrofoil-crystal`
container image as runtime environment.

The included `docker-compose.yml` and `Procfile.dev` files setups everything
that is needed to automatically run the project's specs.

To start watching for changes, in a console:

    $ docker compose up

(Use `docker-compose` if you're still using old version of Docker Compose)

You can press `Ctrl+C` to stop it or from another console:

    $ docker compose stop

[skip ci]
2021-11-27 13:05:37 +01:00
.github/workflows Use GitHub Actions for CI 2021-01-30 20:59:59 -03:00
spec Fix incorrect lookup in non-root nodes 2021-01-30 23:35:53 -03:00
src Prepare for release: v0.4.1 2021-03-23 09:15:56 -03:00
.gitignore misc(git): update ignores for latest version of Crystal 2016-11-24 21:29:13 -03:00
CHANGELOG.md Prepare for release: v0.4.1 2021-03-23 09:15:56 -03:00
LICENSE Extraction: initial import 2016-01-24 19:19:42 -03:00
Procfile.dev Switch dev tooling to containers 2021-11-27 13:05:37 +01:00
README.md Add CI status badge 2021-01-30 21:08:30 -03:00
docker-compose.yml Switch dev tooling to containers 2021-11-27 13:05:37 +01:00
shard.yml Prepare for release: v0.4.1 2021-03-23 09:15:56 -03:00

README.md

Radix Tree

Radix tree implementation for Crystal language

CI Latest Release

Installation

Add this to your application's shard.yml:

dependencies:
  radix:
    github: luislavena/radix

Usage

Building Trees

You can associate a payload with each path added to the tree:

require "radix"

tree = Radix::Tree(Symbol).new
tree.add "/products", :products
tree.add "/products/featured", :featured

result = tree.find "/products/featured"

if result.found?
  puts result.payload # => :featured
end

The types allowed for payload are defined on Tree definition:

tree = Radix::Tree(Symbol).new

# Good, since Symbol is allowed as payload
tree.add "/", :root

# Compilation error, Int32 is not allowed
tree.add "/meaning-of-life", 42

Can combine multiple types if needed:

tree = Radix::Tree(Int32 | String | Symbol).new

tree.add "/", :root
tree.add "/meaning-of-life", 42
tree.add "/hello", "world"

Lookup and placeholders

You can also extract values from placeholders (as named segments or globbing):

tree.add "/products/:id", :product

result = tree.find "/products/1234"

if result.found?
  puts result.params["id"]? # => "1234"
end

Please see Radix::Tree#add documentation for more usage examples.

Caveats

Pretty much all Radix implementations have their limitations and this project is no exception.

When designing and adding paths to a Tree, please consider that two different named parameters cannot share the same level:

tree.add "/", :root
tree.add "/:post", :post
tree.add "/:category/:post", :category_post # => Radix::Tree::SharedKeyError

This is because different named parameters at the same level will result in incorrect params when lookup is performed, and sometimes the value for post or category parameters will not be stored as expected.

To avoid this issue, usage of explicit keys that differentiate each path is recommended.

For example, following a good SEO practice will be consider /:post as absolute permalink for the post and have a list of categories which links to the permalinks of the posts under that category:

tree.add "/", :root
tree.add "/:post", :post                    # this is post permalink
tree.add "/categories", :categories         # list of categories
tree.add "/categories/:category", :category # listing of posts under each category

Implementation

This project has been inspired and adapted from julienschmidt/httprouter and spriet2000/vertx-http-router Go and Java implementations, respectively.

Changes to logic and optimizations have been made to take advantage of Crystal's features.

Contributing

  1. Fork it ( https://github.com/luislavena/radix/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Contributors