Skip to content

A high-performance JSON processing library for the Mojo programming language, providing bindings for the Sonic-RS library and leveraging SIMD for fast JSON parsing and manipulation.

License

Notifications You must be signed in to change notification settings

better-mojo/sonic-mojo

This branch is 17 commits behind furnace-dev/sonic-mojo:main.

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Feb 14, 2025
80d64f2 · Feb 14, 2025

History

34 Commits
Oct 31, 2024
Nov 3, 2024
Nov 23, 2024
Oct 30, 2024
Feb 14, 2025
Feb 14, 2025
Oct 30, 2024
Oct 30, 2024
Oct 30, 2024
Nov 20, 2024
Oct 30, 2024
Nov 23, 2024
Oct 30, 2024
Oct 31, 2024
Nov 23, 2024
Feb 14, 2025
Oct 30, 2024
Jan 24, 2025
Feb 14, 2025

Repository files navigation

sonic-mojo

A high-performance JSON processing library for the Mojo programming language, providing bindings for the Sonic-RS library and leveraging SIMD for fast JSON parsing and manipulation.

Usage

add

  • add channel:
# for libsonic
magic project channel add "https://repo.prefix.dev/better-ffi" 

# for sonic-mojo
magic project channel add "https://repo.prefix.dev/better-mojo-nightly"

  • add package:
magic add sonic_mojo
magic add libsonic

Compile the sonic-rs library

cargo build --release

Generate bindings for sonic-rs

cargo run --release -- generator

Update the files in the internal directory to use the correct library name

sed -i 's/libXXX/libsonic/g' ./sonic/internal/diplomat_runtime.mojo

Run the tests

cp ./target/release/libsonic.so ./

magic shell
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$(realpath .)
mojo test test_sonic.mojo

Package the sonic-mojo library

mojo package ./sonic -o ./sonic_mojo.mojopkg

Examples

Here’s a quick example of how to use Sonic-Mojo to read and write JSON data:

Reading JSON

fn main() raises:
    # Create a JSON object
    var o = JsonObject(
        '{"i64": 1000, "u64": 1000000000000000000, "b": true, "s": "Hi", "obj":'
        ' {"a": 100, "s": "hello"}, "arr": [1,2,3], "s_arr": ["a", "b", "c"],'
        ' "null": null}'
    )

    # Reading
    var i64 = o.get_i64("i64")
    var u64 = o.get_u64("u64")
    var b = o.get_bool("b")
    var s = o.get_str("s")

    # Reading nested object
    var obj = o.get_object_mut("obj")
    var obj_a = obj.get_i64("a")
    var obj_s = obj.get_str("s")

    # Reading array
    var arr = o.get_array_mut("arr")
    var arr_0 = arr.get_i64(0)
    var arr_1 = arr.get_i64(1)
    var arr_2 = arr.get_i64(2)

    # Reading string array
    var s_arr = o.get_array_mut("s_arr")
    var s_arr_len = s_arr.len()
    var s_arr_0 = s_arr.get_str(0)
    var s_arr_1 = s_arr.get_str(1)
    var s_arr_2 = s_arr.get_str(2)

    # Handling null value
    var null = o.get_value("null")
    var i64_2 = o.get_value("i64")

    # Printing results
    print("i64: ", i64)
    print("u64: ", u64)
    print("bool: ", b)
    print("string: ", s)
    print("obj.a: ", obj_a)
    print("obj.s: ", obj_s)
    print("arr[0]: ", arr_0)
    print("arr[1]: ", arr_1)
    print("arr[2]: ", arr_2)
    print("s_arr length: ", s_arr_len)
    print("s_arr[0]: ", s_arr_0)
    print("s_arr[1]: ", s_arr_1)
    print("s_arr[2]: ", s_arr_2)
    print("null is null: ", null.is_null())
    print("i64 is null: ", i64_2.is_null())

Writing JSON

fn main() raises:
    # Create a JSON object
    var o = JsonObject('{"a": {"b": {"c": 100}}}')

    # Get the nested object
    var a = o.get_object_mut("a")
    var b = a.get_object_mut("b")

    # Read the current value
    var c = b.get_i64("c")

    # Output the current value
    print("Initial value of c: ", c)

    # Write a new value
    o.insert_bool("f", True)
    o.insert_u64("g", 1000000000000000000)
    o.insert_i64("d", 101)
    o.insert_str("e", "hello")
    o.insert_array("h", JsonArray())
    o.insert_object("i", JsonObject('{"j": 100}'))

    # Get the updated object
    var a_2 = o.get_object_mut("a")

    # Print the string representation of the nested object
    print("Updated object a: ", a_2.to_string())

    # Print the string representation of the entire JSON object
    print("Updated JSON object: ", o.to_string())

Contributing

Contributions are welcome! If you have suggestions for improvements or new features, please open an issue or submit a pull request. Make sure to follow the contribution guidelines.

License

This project is licensed under the MIT License. See the LICENSE file for more details.

Acknowledgments

  • Sonic-RS for providing the foundation of this library.
  • Diplomat for the code generation tool used to create Mojo bindings, with modifications in my forked version f0cii/diplomat.
  • The community for their support and contributions.

Feel free to modify any sections to better fit your project or add any additional information you think is necessary!

About

A high-performance JSON processing library for the Mojo programming language, providing bindings for the Sonic-RS library and leveraging SIMD for fast JSON parsing and manipulation.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Mojo 82.4%
  • Rust 17.3%
  • Shell 0.3%