DEV Community

Maarten van Vliet
Maarten van Vliet

Posted on

1

TIL - Implementing Encoder for NifStructs

I am currently using Rustler, a tool that allows for Elixir to interact with the Rust ecosystem. As a newcomer to Rust, working on Rust-Elixir crossover libraries helps me understand its quirks.

Today, I was trying to use a SQL parser in Rust and convert the results to Elixir terms. Rustler's NifStructs feature made this process convenient. However, I encountered an issue with a data structure defined as follows:

#[derive(NifStruct)]
#[module = "SqlParser.Select"]
pub struct Select {
    pub selection: Option<Expr>
}
Enter fullscreen mode Exit fullscreen mode

The issue arose when I encountered this enum:

pub enum Expr {
    BinaryOp {
        left: Box<Expr>,
        op: BinaryOperator,
        right: Box<Expr>,
    }
}
Enter fullscreen mode Exit fullscreen mode

Because of the Box<Expr>, this becomes a recursive data structure. To encode this with Rustler, I needed to implement the Encoder trait for Box<Expr>.

impl Encoder for Box<Expr> {
    fn encode<'a>(&self, env: Env<'a>) -> Term<'a>  {
        let data =&** self;
        data.encode(env)
    }
}
Enter fullscreen mode Exit fullscreen mode

However, this caused a chain reaction. The Select struct above has a Decoder trait implemented for it, and it expects Expr to also implement that trait to decode. At first, I implemented the Decoder trait for Expr, but since I only need to use the parser one-way (from SQL through Rust to Elixir) and not vice-versa, this was not necessary.

I had to do a bit of digging but found that I could use:

#[derive(NifStruct)]
#[rustler(encode)]
#[module = "SqlParser.Select"]
Enter fullscreen mode Exit fullscreen mode

and the Select struct would never implement the Decoder trait, resulting in that the Expr also did not need to implement it.

So annotate the code with #[rustler(encode)] or #[rustler(decode)] if you only need one-way
encoding/decoding in Rustler.

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

Top comments (0)

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

πŸ‘‹ Kindness is contagious

Dive into an ocean of knowledge with this thought-provoking post, revered deeply within the supportive DEV Community. Developers of all levels are welcome to join and enhance our collective intelligence.

Saying a simple "thank you" can brighten someone's day. Share your gratitude in the comments below!

On DEV, sharing ideas eases our path and fortifies our community connections. Found this helpful? Sending a quick thanks to the author can be profoundly valued.

Okay