PaulBickford

PaulBickford

How to access a Go library (Pdfcpu) in Elixir using Wasmex?

I have an Elixir module in which I am trying to call out to Pdfcpu to modify existing PDFs. Pdfcpu is written in Go and has a CLI and an API, and I am trying to use the API. I am using Wasmex to run the WASM code and interface with Elixir.

I have created a simple Go module:

package main

import (
    "log"

    "github.com/pdfcpu/pdfcpu/pkg/api"
)

func main() {
}

func RotateFile(inFile, outFile string, rotation int, selectedPages []string) {
    if err := api.RotateFile(inFile, outFile, rotation, []string{"1"}, nil); err != nil {
        log.Fatal(err)
    }
}

then ran

go mod init proj/pdfcpu
go get github.com/pdfcpu/pdfcpu@latest
go mod tidy
GOOS=wasip1 GOARCH=wasm go build -o main.go

To test, I ran a simple Elixir script

api_binary = File.read!("main.wasm")
{:ok, api_pid} = Wasmex.start_link(%{bytes: api_binary, wasi: true})

Wasmex.call_function(api_pid, "RotateFile", ["input.pdf", "output.pdf", 180, [], nil])

And I receive {:error, "exported function `RotateFile` not found"}

RotateFile is in the api package, so I tried calling “api.RotateFile” instead of “RotateFile”, but it made no difference.

What am I doing wrong?

First Post!

Vidar

Vidar

This might or might not be relevant, but anyway: I try to validate and challenge the Elixir skill packages with new projects, and this seemed like a new one with wasm and everything. I’m not a Go person, and Claude insisted using Go with WASM and Elixir had at least 2-3 hurdles to pass before getting there. Hence the switch to Rust and WASM and Elixir, the Extism library for the bridging, and the Rust lopdf library for the pdf.

The showcase is working with a Phoenix Liveview to upload pdf files, various operation per the library, and a preview pane showing the page for rotation and delete etc.

If you can use it for anything it is at GitHub - BadBeta/Experimental_Elixir_Rust_lopdf_wasm_showcase · GitHub .

The production Docker release did not go smooth, so I got my own purpose fulfilled - hole in Claude skills located. (Will update once it is fixed). Having a PDF library around is handy so that is nice too, although I think I prefer a Rustler NIF to the WASM setup.

Any particular reason for the WASM setup? Portability, crash safety?

Most Liked

Vidar

Vidar

It was a new one to me, but Claude insisted this was the one to use for Elixir Rust WASM setup. So as I’m exploring anyway I figured lets give it a try.

Vidar

Vidar

Yes, I figured PDF was common enough to just to give it a background run. Learning some about WASM and this Extism library/ framework was also interesting.

A Rustler NIF will likely be many times faster than going with WASM. On the other hand WASM seems like a good solution for portability and crash safety. In general I’ve found that Elixir and Rust work very well together.

Where Next?

Popular in Questions Top

PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
Lily
In templates/appointment/index.html.eex: <%= for appointment <- @appointments do %> <tr> <td><%= appoi...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

Other popular topics Top

minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 44265 214
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New

We're in Beta

About us Mission Statement