cbor.cr

CBOR (RFC-8949) implementation in Crystal lang.

cbor.cr

a lightweight, dependency-free, high-performance and RFC 8949 compliant CBOR (Concise Binary Object Representation) implementation for the Crystal programming language.

Key Features

  • Full RFC 8949 Compliance: Supports all Major Types (0 to 7).
  • Streaming Support: Encode and decode directly to/from any IO (files, sockets, memory) without loading entire payloads into RAM.
  • Semantic Tags: Native support for CBOR Tags (Major Type 6) to add metadata to your data structures.
  • Type Safety: Seamless integration with Crystal’s type system using the CBOR::Value alias.
  • Diagnostic & Debugging Tools: Utilities for human-readable CBOR diagnostic notation and hex inspection to visualize hierarchy for low-level debugging.

Roadmap & Future Enhancements

  • CBOR::Serializable Module: Implement a high-level API similar to JSON::Serializable for seamless object mapping using class annotations.
  • Extensible Tag Registry: Develop a plugin system to register custom converters for specific CBOR Tags, enabling automatic conversion between custom types and binary data.

Installation

Add the library to your shard.yml:

dependencies:
  cbor:
    github: mamiysr/cbor.cr

Then, install the dependencies:

shards install

Usage

Basic Encoding and Decoding

Transforming data structures to binary and back is straightforward.

require "cbor"

# Create a data structure
data = {
  "name"    => "Crystal",
  "version" => 1.18,
  "active"  => true,
  "tags"    => [1, 2, 3]
}

# Encode: Hash -> Bytes
encoded = CBOR.encode(data)
puts "Encoded size: #{encoded.size} bytes"

# Decode: Bytes -> CBOR::Value -> Hash
decoded = CBOR.decode(encoded).as(Hash)
puts decoded["name"] # => "Crystal"

Streaming (IO-Based Processing)

For large datasets, you can process data chunk-by-chunk using Crystal's IO system to keep memory usage low.

# Write to a file (Encoding)
File.open("data.cbor", "w") do |file|
  CBOR.encode({"sensor_id" => 12345}, file)
end

# Read from a file (Decoding)
File.open("data.cbor", "r") do |file|
  decoded = CBOR.decode(file)
  puts decoded
end

Working with CBOR Tags

Tags are used to provide extra semantic meaning to data (e.g., indicating a string is actually a Date or a UUID).

# Manually create a Tag (e.g., Tag 1 for Date/Time)
date_tag = CBOR::Tag.new(1_u64, "2026-01-14")

encoded = CBOR.encode(date_tag)
decoded = CBOR.decode(encoded).as(CBOR::Tag)

puts "Tag ID: #{decoded.id}"      # => 1
puts "Content: #{decoded.content}" # => "2026-01-14"

Diagnostic & Debugging

.diagnose provides JSON like human-readable text representation of encoded binary data for quick verification, .inspect_hex performs deep structural analysis to visualize exactly how each byte maps to the data hierarchy for low-level debugging.

data = {
  "name"    => "Crystal",
  "version" => 1.18,
  "active"  => true,
  "tags"    => [1, 2, 3]
}

encoded = CBOR.encode(data)

pp CBOR.inspect_hex(encoded)
# Offset | Hex Bytes  | Structure
# -------|------------|----------------
# 0000   | A4           | Map(size: 4)
# 0001   | 64 6E 61 6D_ |   String(4): "name"
# 0006   | 67 43 72 79_ |   String(7): "Crystal"
# 000E   | 67 76 65 72_ |   String(7): "version"
# 0016   | FB 3F F2 E1_ |   Float64: 1.18
# 001F   | 66 61 63 74_ |   String(6): "active"
# 0026   | F5           |   Simple: true
# 0027   | 64 74 61 67_ |   String(4): "tags"
# 002C   | 83           |   Array(size: 3)
# 002D   | 01           |     Positive Int: 1
# 002E   | 02           |     Positive Int: 2
# 002F   | 03           |     Positive Int: 3

puts CBOR.diagnose(encoded) # => {"name": "Crystal", "version": 1.18, "active": true, "tags": [1, 2, 3]}

Contributing

  1. Fork it (https://github.com/mamiysr/cbor.cr/fork)
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

License

MIT License.

Repository

cbor.cr

Owner
Statistic
  • 0
  • 0
  • 0
  • 0
  • 0
  • about 18 hours ago
  • January 13, 2026
License

MIT License

Links
Synced at

Thu, 15 Jan 2026 08:05:42 GMT

Languages