jason-rs 0.2.15

A library for parsing Jason-like files into JSON, YAML, or TOML with support for inline file expansion.
docs.rs failed to build jason-rs-0.2.15
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Visit the last successful build: jason-rs-0.2.7

jason-RS

Crates.io Docs License

jason is a lightweight JSON templating tool that transforms reusable .jason files into standard JSON. Build modular and composable JSON structures with parameter support and file inclusion.

✨ Features

  • Template Parameters - Define reusable templates with named parameters
  • File Inclusion - Compose JSON from multiple .jason files
  • 1:1 Conversion - Clean mapping from .jason syntax to standard JSON
  • Library-First - Designed for seamless integration into Rust projects

🚀 Quick Start

Add jason-rs to your Cargo.toml:

[dependencies]
jason-rs = "0.2.5"

Parse a Jason file:

use jason_rs::jason_to_json;

fn main() {
    //outputs raw json source
    let json = jason_to_json("./Page.jason").unwrap();
    println!("{}", json);
}

Example

Jason File

//a variable that holds a value
project_name = "jason-rs"

//what gets exported at the top level
out {
    name: "Alex",
    project: "jason-rs",
    money: 0,
}

Jason Templates

Dev(name, project, money) {
    name: name,
    project: project,
    money: money,
}
// invokes the template and fills in the variables with the passed in arguments
out Dev("alex", "jason-rs", 0) 

importing

Dev.jason - A file containg the dev template

Dev(name, project, money) {
    name: name,
    project: project,
    money: money,
}

main.jason - The top level file being compiled

import(Dev) from "./Person.jason"

out Dev("alex", "jason-rs", 0) 

* operator

The * operator repeats an expression an integer number of times and then stores it in a list.

//this returns ["hello👋","hello👋","hello👋","hello👋","hello👋","hello👋","hello👋","hello👋","hello👋","hello👋","hello👋","hello👋"]
out  "hello👋" * 12

pick_example.jason

Person(name, age) {
    name: name,
    age: age
}
//makes a Person witha random name and int from 0 to 67. 2000 times and stores them into a list
main = Person(random_name()!, random_int(67)!) * 2000
//pick one value from main 12 times
result = pick(main)!*12
//out the result
out result

note: this will not import the context around DEV so variables will be ignored unless imported as well. this warning will be patched in a later version with groups.

JasonBuilder

JasonBuilder allows you to add Lua dependencies to your .jason parsing pipeline.

Start with no Lua dependencies:

use jason_rs::JasonBuilder;

let builder = JasonBuilder::new();

Adding Lua Dependencies

Include Lua files:

let builder = JasonBuilder::new()
    .include_lua_file("scripts/helpers.lua")?
    .include_lua_file("scripts/math.lua")?;

Or raw Lua source:

let lua_code = r#"function add(a,b) return a+b end"#;
let builder = JasonBuilder::new().include_lua(lua_code)?;

Both methods are chainable, allowing you to add multiple Lua dependencies easily.

Then you can just run the standard functions from converting jason to json using builder

fn main() -> Result<(), Box<dyn std::error::Error>>{
    let result = jason_rs::JasonBuilder::new()
        .include_lua(r#"
            -- Returns the part of `text` before the first occurrence of `delimiter`
            function split_first(text, delimiter)
                local delim_start, _ = string.find(text, delimiter, 1, true)
                if delim_start then
                    return string.sub(text, 1, delim_start - 1)
                else
                    return text  -- no delimiter found, return the whole string
                end
            end
        "#)?.jason_src_to_json(r#"            
            User(email, password, ip) {
                email: email,
                password: password,
                username: split_first(email, "@")!,
                ip: ip
            }
            out User(random_email()!, random_password()!, random_ipv4()!) * 2 
        "#)?;         
    println!("{}", serde_json::to_string_pretty(&result)?);
    Ok(())
}

result

[
  {
    "email": "ptcbkvhhda@www.example.com",
    "ip": "103.121.162.79",
    "password": "qMdC&PK0y8=s",
    "username": "ptcbkvhhda"
  },
  {
    "email": "aabzlr@api.demo.org",
    "ip": "69.44.42.254",
    "password": "DLPng64XhkQF",
    "username": "aabzlr"
  }
]

Errors

Error outputs are nice and concise and propogate nicly.

Example error

Error: Lua Function Error in file ./main.jason on line 8: failed to find function random_name: error converting Lua nil to function
    8 |  out Some(Person(random_name()!, random_int(30)!)) * 50
                         ^^^^^^^^^^^^^^                        

Syntax Overview

Syntax Description
name(arg1, arg2, ...) {...} Defines a template name
name() {...} Defines a template name
name = ... Defines a variable name
name(...) invokes a template
import(template, variable, ...) from "path/to/file.jason" imports templates and or variables from file
import(*) from "path/to/file.jason" imports all templates and all variables from a file
import($) from "path/to/file.jason" imports all variables from a file
func(...)! calls a built in function with passed in arguments
expression * n OR n * expression repeats expression a positive integer n times and stores it as a list
out <jason expression> when the file gets read from at the top level the value is what gets returned
{...} + {...} Object concat yeilds {name: "Alex"} + {age: 20} = {name: "Alex", age: 20}. Note it overrides keys with right dominance
[...] + [...] list concat expressions. yeilds [1,2,3] + [4,5] = [1,2,3,4,5]
"..." + "..." String concat yeilds "hello" + " world" = "hello world". strings support unicode!

Parses a .jason file at the given path and returns a serde_json value object which can then be converted to structs

License

Licensed under the Apache License 2.0. See LICENSE for details.