ToonParser
A Ruby gem for parsing and serializing TOON (Token-Oriented Object Notation) format. TOON is a compact, human-readable data format designed to reduce token usage in LLM applications by 30-60% compared to JSON.
Table of Contents
- Features
- Installation
- Quick Start
- Usage
- Basic Parsing
- Basic Serialization
- File Operations
- Rails Controller Integration
- API Integration
- Advanced Usage
- TOON Format Overview
- Examples
- Development
- Contributing
- License
Features
✨ Key Features:
- 🚀 Fast parsing and serialization of TOON format
- 🎯 Rails integration - Use TOON in controllers instead of JSON
- 📦 File operations - Read and write TOON files
- 🌐 API helpers - Built-in HTTP client for TOON APIs
- 🔄 Round-trip conversion - Parse and serialize without data loss
- 🎨 Type inference - Automatic detection of numbers, booleans, and null
- 📝 Human-readable - Compact yet readable format
- 🔌 Optional Rails dependency - Works standalone or with Rails
Installation
Add this line to your application's Gemfile:
gem 'toon-parser'And then execute:
$ bundle installOr install it yourself as:
$ gem install toon-parserQuick Start
require 'toon-parser'
# Parse TOON string
toon = "users[2]{id,name}:\n 1,Alice\n 2,Bob"
data = ToonParser.parse(toon)
# => {"users" => [{"id" => 1, "name" => "Alice"}, {"id" => 2, "name" => "Bob"}]}
# Serialize to TOON
data = { "users" => [{ "id" => 1, "name" => "Alice" }] }
toon = ToonParser.serialize(data)
# => "users[1]{id,name}:\n 1,Alice"Usage
Basic Parsing
Parse a TOON string into Ruby objects:
require 'toon-parser'
toon = <<~TOON
users[2]{id,name}:
1,Alice
2,Bob
TOON
data = ToonParser.parse(toon)
# => {"users" => [{"id" => 1, "name" => "Alice"}, {"id" => 2, "name" => "Bob"}]}Basic Serialization
Convert Ruby objects to TOON format:
data = {
"users" => [
{ "id" => 1, "name" => "Alice" },
{ "id" => 2, "name" => "Bob" }
]
}
toon = ToonParser.serialize(data)
# => "users[2]{id,name}:\n 1,Alice\n 2,Bob"File Operations
Parse a TOON file:
data = ToonParser.parse_file("data.toon")Serialize to a TOON file:
ToonParser.serialize_to_file(data, "output.toon")Rails Controller Integration
Use TOON format in your Rails controllers instead of JSON. The gem automatically integrates with Rails when available.
Basic Controller Usage
# app/controllers/api/users_controller.rb
class Api::UsersController < ApplicationController
before_action :set_toon_format
def index
@users = User.all
render toon: {
users: @users.map { |u| { id: u.id, name: u.name, email: u.email } }
}
end
def show
@user = User.find(params[:id])
render toon: {
user: { id: @user.id, name: @user.name, email: @user.email }
}
end
def create
# TOON request body is automatically parsed if Content-Type is application/toon
user_data = parse_toon_request
@user = User.create(user_data)
if @user.persisted?
render toon: { user: @user }, status: :created
else
render toon: { errors: @user.errors.full_messages }, status: :unprocessable_entity
end
end
private
def set_toon_format
request.format = :toon if request.format == :html
end
endSetting Default Format
Set TOON as the default format for API controllers:
# app/controllers/api/base_controller.rb
class Api::BaseController < ApplicationController
before_action :set_toon_format
private
def set_toon_format
request.format = :toon if request.format == :html
end
endResponding to Multiple Formats
Support both TOON and JSON:
class Api::UsersController < ApplicationController
def index
@users = User.all
data = { users: @users.map { |u| { id: u.id, name: u.name } } }
respond_to do |format|
format.toon { render toon: data }
format.json { render json: data }
end
end
endParsing TOON Request Bodies
The gem automatically registers a parameter parser for TOON request bodies. When a request has Content-Type: application/toon, Rails will automatically parse the body. You can also manually parse:
class Api::UsersController < ApplicationController
def create
# Option 1: Automatic parsing (if Content-Type is application/toon)
# The body is automatically parsed into params
# Option 2: Manual parsing
user_data = parse_toon_request
@user = User.create(user_data)
render toon: { user: @user }
end
endNote: The automatic parameter parser only works if the request has Content-Type: application/toon header. For manual parsing, use the parse_toon_request helper method.
Routes Configuration
Configure routes to accept TOON format:
# config/routes.rb
Rails.application.routes.draw do
namespace :api do
resources :users, defaults: { format: :toon }
end
endAvailable Controller Helpers
-
render_toon(data, options = {})- Render TOON response -
parse_toon_request- Parse TOON request body -
set_toon_format- Set TOON as default format -
respond_to_toon(data, options = {})- Support multiple formats
API Integration
Use the API helper for TOON-formatted API requests and responses:
# Create an API client
api = ToonParser.api("https://api.example.com", headers: { "Authorization" => "Bearer token" })
# GET request
users = api.get("/users")
# POST request with TOON body
new_user = api.post("/users", data: { "name" => "Alice", "email" => "alice@example.com" })
# PUT request
updated = api.put("/users/1", data: { "name" => "Alice Updated" })
# PATCH request
patched = api.patch("/users/1", data: { "name" => "Alice Patched" })
# DELETE request
api.delete("/users/1")Advanced Usage
Nested Objects
toon = <<~TOON
user:
id: 1
name: Alice
profile:
age: 30
city: New York
TOON
data = ToonParser.parse(toon)
# => {"user" => {"id" => 1, "name" => "Alice", "profile" => {"age" => 30, "city" => "New York"}}}Arrays of Primitives
toon = <<~TOON
numbers[3]:
1
2
3
TOON
data = ToonParser.parse(toon)
# => {"numbers" => [1, 2, 3]}Boolean and Null Values
toon = <<~TOON
data:
active: true
deleted: false
value: null
TOON
data = ToonParser.parse(toon)
# => {"data" => {"active" => true, "deleted" => false, "value" => nil}}Floating Point Numbers
toon = <<~TOON
prices[2]:
19.99
29.50
TOON
data = ToonParser.parse(toon)
# => {"prices" => [19.99, 29.50]}TOON Format Overview
TOON uses a compact syntax that eliminates unnecessary brackets, quotes, and whitespace:
JSON:
{
"users": [
{ "id": 1, "name": "Alice" },
{ "id": 2, "name": "Bob" }
]
}TOON:
users[2]{id,name}:
1,Alice
2,Bob
Key Features
-
Array notation:
[size]indicates array length -
Object schema:
{field1,field2}defines object structure - Tabular data: Rows are comma-separated values
- Type inference: Numbers, booleans, and null are automatically detected
- Indentation: Used for nesting and structure
- Compact: 30-60% smaller than JSON for typical data structures
Examples
See the examples directory for more usage examples:
- Rails Controller Example - Complete Rails controller implementation
Development
After checking out the repo, run:
$ bundle installTo run the test suite:
$ bundle exec rspecOr run tests directly:
$ rspec spec/To install this gem onto your local machine, run:
$ bundle exec rake installTo release a new version:
- Update the version number in
lib/toon-parser/version.rb - Run
bundle exec rake release
This will create a git tag for the version, push git commits and the created tag, and push the .gem file to rubygems.org.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Development Setup
# Clone the repository
git clone https://github.com/afshmini/toon-parser.git
cd toon-parser
# Install dependencies
bundle install
# Run tests
bundle exec rspec
# Run linter
bundle exec rubocopLicense
The gem is available as open source under the terms of the MIT License.
Links
- GitHub Repository
- Issue Tracker
- RubyGems (when published)
Acknowledgments
- Inspired by the TOON format specification
- Designed to reduce token usage in LLM applications