acha.ninja

JSON in Janet Shell

In this post I will demonstrate how we can load native Janet extensions at runtime to add powerful new functionality to your janet programs (In this case Janet Shell). For this demo, we will be installing a native JSON extension and loading it into a running shell session so we can do JSON manipulation from the terminal.

Installing the JSON extension

The first step is to choose where to install our extensions and add it to our janet module path. To do this I added the following line to my ~/.janetsh.rc file:

# Tell janet it can load janet and native modules from ~/janet-modules
(array/insert module/paths 0 
   [(string (os/getenv "HOME") "/janet-modules/:all:.janet") :source]
   [(string (os/getenv "HOME") "/janet-modules/:all:.:native:") :native])

The next step is to install the JSON module, currently on linux we use git to fetch the source and the jpm program that comes with the latest janet to build it into a native module:

$ git clone https://github.com/janet-lang/json/
...
$ cd json
$ jpm build
...
$ cp ./build/json.so ~/janetsh-modules

Using the module

Now that we can enjoy JSON from Janet Shell, let’s print all the astronauts currently in space and which space craft they are in:

# Import the module into our shell session.
$ (import json)

# Download and decode list of astronauts in space.
$ (var astronauts-in-space
    (json/decode ($$ curl http://api.open-notify.org/astros.json)))

# Print each one and the space craft they are in.
$ (each astronaut (astronauts-in-space "people")
    (print
      "Name: " (astronaut "name") 
      ", Craft: " (astronaut "craft")))
...
Name: Oleg Kononenko, Craft: ISS
Name: David Saint-Jacques, Craft: ISS
Name: Anne McClain, Craft: ISS
...

We could also easily do more sophisticated things like writing functions to encapsulate this functionality, or manipulate the data in some way.

Conclusion

With Janet Shell you can extend your shell at runtime by using Janet’s powerful module system. I should also note modules can be written in Janet, C, Rust, Zig … or in otherwords, basically anything you want with the right know how.

As always, thank you for reading.