Skip to main content

RadixNode

Struct RadixNode 

Source
pub struct RadixNode<V> {
    pub path: Bytes,
    pub data: Option<V>,
    pub rule: RadixRule,
    pub next: RadixPack<V>,
}
Expand description

The basic element inside a tree

Fields§

§path: Bytes

The key of the radix map, valid in data-node only

§data: Option<V>

The value of the radix map, valid in data-node only

§rule: RadixRule

The pattern used for matching, supports plain text, named param, glob and regex

§next: RadixPack<V>

Node’s children

Implementations§

Source§

impl<V> RadixNode<V>

Source

pub fn is_empty(&self) -> bool

Check if the node has no data

Source

pub fn item_ref(&self) -> Option<(&Bytes, &V)>

Get path-data pair

Source

pub fn item_mut(&mut self) -> Option<(&Bytes, &mut V)>

Get path-data pair

Source

pub fn iter(&self) -> Iter<'_, V>

An iterator for node

§Examples
use bytes::Bytes;
use radixmap::{node::RadixNode, RadixResult};

fn main() -> RadixResult<()> {
    let mut node = RadixNode::default();
    node.insert("/api", "api")?;
    node.insert("/api/v1", "v1")?;
    node.insert("/api/v2", "v2")?;

    let mut iter = node.iter();

    assert_eq!(iter.next().and_then(|node| node.item_ref()), Some((&Bytes::from("/api"), &"api")));
    assert_eq!(iter.next().and_then(|node| node.item_ref()), Some((&Bytes::from("/api/v1"), &"v1")));
    assert_eq!(iter.next().and_then(|node| node.item_ref()), Some((&Bytes::from("/api/v2"), &"v2")));
    assert_eq!(iter.next().and_then(|node| node.item_ref()), None);

    Ok(())
}
Source

pub fn iter_mut(&mut self) -> IterMut<'_, V>

A mutable iterator for node

§Examples
use bytes::Bytes;
use radixmap::{node::RadixNode, RadixResult};

fn main() -> RadixResult<()> {
    let mut node = RadixNode::default();
    node.insert("/api", 0)?;
    node.insert("/api/v1", 1)?;
    node.insert("/api/v2", 2)?;

    for node in node.iter_mut() {
        node.data = Some(node.data.unwrap_or_default() + 10);
    }

    let mut iter = node.iter_mut();

    assert_eq!(iter.next().and_then(|node| node.item_mut()), Some((&Bytes::from("/api"), &mut 10)));
    assert_eq!(iter.next().and_then(|node| node.item_mut()), Some((&Bytes::from("/api/v1"), &mut 11)));
    assert_eq!(iter.next().and_then(|node| node.item_mut()), Some((&Bytes::from("/api/v2"), &mut 12)));
    assert_eq!(iter.next().and_then(|node| node.item_mut()), None);

    Ok(())
}
Source

pub fn keys(&self) -> Keys<'_, V>

Iterator adapter for path

§Examples
use bytes::Bytes;
use radixmap::{node::RadixNode, RadixResult};

fn main() -> RadixResult<()> {
    let mut node = RadixNode::default();
    node.insert("/api", ())?;
    node.insert("/api/v1", ())?;
    node.insert("/api/v2", ())?;

    let mut iter = node.keys();

    assert_eq!(iter.next(), Some(&Bytes::from("/api")));
    assert_eq!(iter.next(), Some(&Bytes::from("/api/v1")));
    assert_eq!(iter.next(), Some(&Bytes::from("/api/v2")));
    assert_eq!(iter.next(), None);

    Ok(())
}
Source

pub fn values(&self) -> Values<'_, V>

Iterator adapter for data

§Examples
use radixmap::{node::RadixNode, RadixResult};

fn main() -> RadixResult<()> {
    let mut node = RadixNode::default();
    node.insert("/api", 0)?;
    node.insert("/api/v1", 1)?;
    node.insert("/api/v2", 2)?;

    let mut iter = node.values();

    assert_eq!(iter.next(), Some(&0));
    assert_eq!(iter.next(), Some(&1));
    assert_eq!(iter.next(), Some(&2));
    assert_eq!(iter.next(), None);

    Ok(())
}
Source

pub fn values_mut(&mut self) -> ValuesMut<'_, V>

Mutable iterator adapter for data

§Examples
use radixmap::{node::RadixNode, RadixResult};

fn main() -> RadixResult<()> {
    let mut node = RadixNode::default();
    node.insert("/api", 0)?;
    node.insert("/api/v1", 1)?;
    node.insert("/api/v2", 2)?;

    for node in node.iter_mut() {
        node.data = Some(node.data.unwrap_or_default() + 10);
    }

    let mut iter = node.values_mut();

    assert_eq!(iter.next(), Some(&mut 10));
    assert_eq!(iter.next(), Some(&mut 11));
    assert_eq!(iter.next(), Some(&mut 12));
    assert_eq!(iter.next(), None);

    Ok(())
}
Source

pub fn insert( &mut self, path: impl Into<Bytes>, data: V, ) -> RadixResult<Option<V>>

Inserts a path and data into this node, which serves as the root node for the insertion. The method sequentially extracts path fragments and positions each node appropriately, ensuring that nodes with a common prefix share a single node in the tree.

Source

pub fn lookup<'u>( &self, path: &'u [u8], data: bool, raw: bool, capture: &mut Vec<(Bytes, &'u [u8])>, enable: bool, ) -> Option<&RadixNode<V>>

Finds the deepest node that matches the given path.

  • If data is true, the function returns the deepest node that is a data node and matches the path exactly.
  • If data is false, the function returns the deepest node that matches the path as far as possible, regardless of whether it is a data node or not.
§Examples
use bytes::Bytes;
use radixmap::{node::RadixNode, RadixResult};

fn main() -> RadixResult<()> {
    let mut node = RadixNode::default();
    node.insert("/api", "api")?;
    node.insert("/api/v1", "v1")?;
    node.insert("/api/v2", "v2")?;
    node.insert("/api/v1/user/:id", "user1")?;
    node.insert("/api/v2/user/{id:[^0-9]+}", "user2")?;
    node.insert("/api/v3/user/*cde", "user3")?;

    assert_eq!(node.lookup(b"/", false, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from("/api")));
    assert_eq!(node.lookup(b"/api", false, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from("/api")));
    assert_eq!(node.lookup(b"/api/v", false, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from("/v")));
    assert_eq!(node.lookup(b"/api/v1", false, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from("1")));
    assert_eq!(node.lookup(b"/api/v2", false, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from("2")));
    assert_eq!(node.lookup(b"/api/v3", false, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from("3/user/")));

    assert_eq!(node.lookup(b"/", true, false, &mut vec![], false).map(|node| node.rule.origin()), None);
    assert_eq!(node.lookup(b"/api", true, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from("/api")));
    assert_eq!(node.lookup(b"/api/v", true, false, &mut vec![], false).map(|node| node.rule.origin()), None);
    assert_eq!(node.lookup(b"/api/v1", true, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from("1")));
    assert_eq!(node.lookup(b"/api/v2", true, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from("2")));
    assert_eq!(node.lookup(b"/api/v1/user/", true, false, &mut vec![], false).map(|node| node.rule.origin()), None);
    assert_eq!(node.lookup(b"/api/v1/user/12345", true, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from(":id")));
    assert_eq!(node.lookup(b"/api/v2/user/12345", true, false, &mut vec![], false).map(|node| node.rule.origin()), None);
    assert_eq!(node.lookup(b"/api/v2/user/abcde", true, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from("{id:[^0-9]+}")));
    assert_eq!(node.lookup(b"/api/v3/user/12345", true, false, &mut vec![], false).map(|node| node.rule.origin()), None);
    assert_eq!(node.lookup(b"/api/v3/user/abcde", true, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from("*cde")));

    Ok(())
}
Source

pub fn lookup_mut<'u>( &mut self, path: &'u [u8], data: bool, raw: bool, capture: &mut Vec<(Bytes, &'u [u8])>, enable: bool, ) -> Option<&mut RadixNode<V>>

Same as lookup

§Examples
use bytes::Bytes;
use radixmap::{node::RadixNode, RadixResult};

fn main() -> RadixResult<()> {
    let mut node = RadixNode::default();
    node.insert("/api", "api")?;
    node.insert("/api/v1", "v1")?;
    node.insert("/api/v2", "v2")?;
    node.insert("/api/v1/user/:id", "user1")?;
    node.insert("/api/v2/user/{id:[^0-9]+}", "user2")?;
    node.insert("/api/v3/user/*cde", "user3")?;

    assert_eq!(node.lookup_mut(b"/", false, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from("/api")));
    assert_eq!(node.lookup_mut(b"/api", false, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from("/api")));
    assert_eq!(node.lookup_mut(b"/api/v", false, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from("/v")));
    assert_eq!(node.lookup_mut(b"/api/v1", false, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from("1")));
    assert_eq!(node.lookup_mut(b"/api/v2", false, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from("2")));
    assert_eq!(node.lookup_mut(b"/api/v3", false, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from("3/user/")));

    assert_eq!(node.lookup_mut(b"/", true, false, &mut vec![], false).map(|node| node.rule.origin()), None);
    assert_eq!(node.lookup_mut(b"/api", true, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from("/api")));
    assert_eq!(node.lookup_mut(b"/api/v", true, false, &mut vec![], false).map(|node| node.rule.origin()), None);
    assert_eq!(node.lookup_mut(b"/api/v1", true, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from("1")));
    assert_eq!(node.lookup_mut(b"/api/v2", true, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from("2")));
    assert_eq!(node.lookup_mut(b"/api/v1/user/", true, false, &mut vec![], false).map(|node| node.rule.origin()), None);
    assert_eq!(node.lookup_mut(b"/api/v1/user/12345", true, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from(":id")));
    assert_eq!(node.lookup_mut(b"/api/v2/user/12345", true, false, &mut vec![], false).map(|node| node.rule.origin()), None);
    assert_eq!(node.lookup_mut(b"/api/v2/user/abcde", true, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from("{id:[^0-9]+}")));
    assert_eq!(node.lookup_mut(b"/api/v3/user/12345", true, false, &mut vec![], false).map(|node| node.rule.origin()), None);
    assert_eq!(node.lookup_mut(b"/api/v3/user/abcde", true, false, &mut vec![], false).map(|node| node.rule.origin()), Some(&Bytes::from("*cde")));

    Ok(())
}
Source

pub fn divide(&mut self, len: usize) -> RadixResult<RadixNode<V>>

Divide the node into two parts

§Examples
use radixmap::{node::RadixNode, RadixResult};

fn main() -> RadixResult<()> {
    let mut node = RadixNode::try_from(("/api", 12345))?;

    assert_eq!(node.rule, b"/api");
    assert_eq!(node.data, Some(12345));

    let frag = node.divide(1)?;

    assert_eq!(node.rule, b"/");
    assert_eq!(node.data, None);
    assert_eq!(frag.rule, b"api");
    assert_eq!(frag.data, Some(12345));

    Ok(())
}
Source

pub fn clear(&mut self)

Clear the nodes but preserve its capacity

§Examples
use radixmap::{node::RadixNode, RadixResult};

fn main() -> RadixResult<()> {
    let mut node = RadixNode::try_from(("/api", ()))?;
    node.insert("/api/v1", ())?;

    assert_eq!(node.is_empty(), false);

    node.clear();

    assert_eq!(node.is_empty(), true);

    Ok(())
}

Trait Implementations§

Source§

impl<V: Clone> Clone for RadixNode<V>

Clone trait

use radixmap::{node::RadixNode, RadixResult};

fn main() -> RadixResult<()> {
    let mut node_a = RadixNode::try_from(("/api", 123))?;
    let mut node_b = node_a.clone();

    assert_eq!(node_a.path, node_b.path);
    assert_eq!(node_a.data, node_b.data);
    assert_eq!(node_a.rule, node_b.rule);

    Ok(())
}
Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<V> Debug for RadixNode<V>

Debug trait

§Examples

use radixmap::{node::RadixNode, RadixResult};

fn main() -> RadixResult<()> {
    assert_eq!(format!("{:?}", RadixNode::try_from((r"/api", ()))?).as_str(), r"Plain(/api)");
    assert_eq!(format!("{:?}", RadixNode::try_from((r":id", ()))?).as_str(), r"Param(:id)");
    assert_eq!(format!("{:?}", RadixNode::try_from((r"*", ()))?).as_str(), r"Glob(*)");
    assert_eq!(format!("{:?}", RadixNode::try_from((r"{id:\d+}", ()))?).as_str(), r"Regex({id:\d+})");

    Ok(())
}
Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<V> Default for RadixNode<V>

Default trait

use radixmap::{node::RadixNode};

let mut node = RadixNode::default();
assert!(node.insert("/api", ()).is_ok());
Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'n, V> From<&'n RadixNode<V>> for Iter<'n, V>

Source§

fn from(start: &'n RadixNode<V>) -> Self

Converts to this type from the input type.
Source§

impl<'n, V> From<&'n RadixNode<V>> for Keys<'n, V>

Source§

fn from(value: &'n RadixNode<V>) -> Self

Converts to this type from the input type.
Source§

impl<'n, V> From<&'n RadixNode<V>> for Values<'n, V>

Source§

fn from(value: &'n RadixNode<V>) -> Self

Converts to this type from the input type.
Source§

impl<'n, V> From<&'n RadixNode<V>> for Iter<'n, V>

Source§

fn from(value: &'n RadixNode<V>) -> Self

Converts to this type from the input type.
Source§

impl<'n, V> From<&'n mut RadixNode<V>> for IterMut<'n, V>

Source§

fn from(start: &'n mut RadixNode<V>) -> Self

Converts to this type from the input type.
Source§

impl<'n, V> From<&'n mut RadixNode<V>> for ValuesMut<'n, V>

Source§

fn from(value: &'n mut RadixNode<V>) -> Self

Converts to this type from the input type.
Source§

impl<'n, V> From<&'n mut RadixNode<V>> for IterMut<'n, V>

Source§

fn from(value: &'n mut RadixNode<V>) -> Self

Converts to this type from the input type.
Source§

impl<V> From<RadixRule> for RadixNode<V>

Create a node from a rule

§Examples

use radixmap::{node::RadixNode, rule::RadixRule, RadixResult};

fn main() -> RadixResult<()> {
    assert_eq!(RadixNode::<()>::from(RadixRule::try_from("/api")?).rule, b"/api");
    assert_eq!(RadixNode::<()>::from(RadixRule::try_from(":id")?).rule, b":id");

    Ok(())
}
Source§

fn from(rule: RadixRule) -> Self

Converts to this type from the input type.
Source§

impl<V> TryFrom<(&'static [u8], V)> for RadixNode<V>

Create a node from (path, data)

Source§

type Error = RadixError

The type returned in the event of a conversion error.
Source§

fn try_from((path, data): (&'static [u8], V)) -> RadixResult<Self>

Performs the conversion.
Source§

impl<V> TryFrom<(&'static str, V)> for RadixNode<V>

Create a node from (path, data)

Source§

type Error = RadixError

The type returned in the event of a conversion error.
Source§

fn try_from((path, data): (&'static str, V)) -> RadixResult<Self>

Performs the conversion.
Source§

impl<V> TryFrom<(Bytes, V)> for RadixNode<V>

Create a node from (path, data)

§Examples

use radixmap::{node::RadixNode, RadixResult};

fn main() -> RadixResult<()> {
    assert_eq!(RadixNode::try_from(("/api", ()))?.rule, b"/api");
    assert_eq!(RadixNode::try_from((":id", ()))?.rule, b":id");

    Ok(())
}
Source§

type Error = RadixError

The type returned in the event of a conversion error.
Source§

fn try_from((path, data): (Bytes, V)) -> RadixResult<Self>

Performs the conversion.

Auto Trait Implementations§

§

impl<V> !Freeze for RadixNode<V>

§

impl<V> RefUnwindSafe for RadixNode<V>
where V: RefUnwindSafe,

§

impl<V> Send for RadixNode<V>
where V: Send,

§

impl<V> Sync for RadixNode<V>
where V: Sync,

§

impl<V> Unpin for RadixNode<V>
where V: Unpin,

§

impl<V> UnsafeUnpin for RadixNode<V>
where V: UnsafeUnpin,

§

impl<V> UnwindSafe for RadixNode<V>
where V: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.