{"id":15066792,"url":"https://github.com/mcorino/firm","last_synced_at":"2025-04-10T13:53:15.144Z","repository":{"id":256765647,"uuid":"851107971","full_name":"mcorino/firm","owner":"mcorino","description":"Format Independent Ruby Marshalling","archived":false,"fork":false,"pushed_at":"2025-01-23T07:36:09.000Z","size":121,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-24T12:39:16.738Z","etag":null,"topics":["cross-platform","marshaling","ruby","serialization"],"latest_commit_sha":null,"homepage":"https://mcorino.github.io/firm/","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mcorino.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-02T12:45:17.000Z","updated_at":"2025-03-22T21:59:10.000Z","dependencies_parsed_at":"2024-09-13T00:32:13.714Z","dependency_job_id":"09ff2fa1-815b-4e35-9121-179be831c405","html_url":"https://github.com/mcorino/firm","commit_stats":null,"previous_names":["mcorino/firm"],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcorino%2Ffirm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcorino%2Ffirm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcorino%2Ffirm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcorino%2Ffirm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mcorino","download_url":"https://codeload.github.com/mcorino/firm/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248229021,"owners_count":21068805,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cross-platform","marshaling","ruby","serialization"],"created_at":"2024-09-25T01:12:08.173Z","updated_at":"2025-04-10T13:53:15.127Z","avatar_url":"https://github.com/mcorino.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Tests](https://github.com/mcorino/firm/actions/workflows/ruby.yml/badge.svg)](https://github.com/mcorino/firm/actions/workflows/ruby.yml)\n\n[![License](https://img.shields.io/badge/license-MIT-yellowgreen.svg)](LICENSE)\n[![Gem Version](https://badge.fury.io/rb/firm.svg)](https://badge.fury.io/rb/firm)\n[![Documentation](https://img.shields.io/badge/docs-pages-blue.svg)](https://mcorino.github.io/firm)\n\n# FIRM - Format Independent Ruby Marshalling\n\n## Introduction\n\nFIRM is a pure Ruby library that works across different Ruby implementations like MRI Ruby and JRuby providing format \nindependent object (de-)serialization support.\n\nFIRM is explicitly **NOT** intended as a non-discriminative marshaling library (dumping any object's attributes)\nbut rather as a structured and safe serialization library requiring users to think about what state they want\npersisted (and possibly in what form) and what not.\nStraightforward attribute serialization is simple with minimal intrusion on user code.\nIn addition various customization options are available to tweak (de-)serialization for a perfect fit if needed. \n\nOut of the box (de-)serializing Ruby objects to(from) JSON and YAML is supported without any additional\ndependencies.\nWhen the `nokogiri` gem is installed (and loaded before FIRM) XML (de-)serializing will also be available.\n\nFIRM supports (de-)serializing many core Ruby objects out of the box including:\n\n- `NilClass`\n- `TrueClass` \u0026 `FalseClass`\n- `Integer`\n- `Float`\n- `Rational`\n- `Complex`\n- `BigDecimal` (if loaded; not default anymore starting from Ruby 3.4)\n- `String`\n- `Symbol`\n- `Array`\n- `Hash`\n- `Range`\n- `Regexp`\n- `Time`\n- `Struct`\n- `Set`\n- `OpenStruct` (optional starting from Ruby 3.5 which removes this class from the standard library)\n- `Date`\n- `DateTime`\n\nFor simplicity and security reasons FIRM does **not** support direct (de-)serializing of `Class` objects but will rather\nserialize (and deserialize) these as their scoped string names. Customized property setters can be used to\nresolve Class objects from these names if really needed.\n\nSerialization support for user defined classes is available through a simple DSL scheme.\n\nFIRM provides object aliasing support for JSON and XML in a similar fashion as the standard support provided\nby YAML.\u003cbr\u003e\nIn addition FIRM automatically recognizes and handles cyclic references of aliasable objects.\n\nFIRM serialization is also thread safe and supports re-entrancy (i.e. nested serialization).\n\n## Installing FIRM\n\nFIRM is distributed as a Ruby gem on [RubyGems](https://rubygems.org). This gem can also be downloaded from the release\nassets on [Github](https://github.com/mcorino/firm/releases).\n\nInstalling the gem requires no additional installation steps and/or additional software to be installed except for a\nsupported version of the Ruby interpreter. So the following command is all it takes to install:\n\n```shell\ngem install firm\n```\n\nInstalling the `nokogiri` gem is optional to enable the XML serialization format.   \n\n## Usage examples\n\n### Serialize an array of objects to JSON string\n\n```\nruby\nrequire 'firm'\n\na = [1, '2', :three, 4.321]\njson = a.serialize\nFIRM.deserialize(json)\n```\n\nIRB output:\n\n```shell\n=\u003e true\n=\u003e \n[1,\n \"2\",\n :three,\n 4.321]\n=\u003e \"[1,\\\"2\\\",{\\\"json_class\\\":\\\"Symbol\\\",\\\"s\\\":\\\"three\\\"},4.321]\"\n=\u003e \n[1,\n \"2\",\n :three,\n 4.321]\n```\n\nAlternatively the object can be serialized to the YAML or XML (if the `nokogiri` gem is installed) format like this.\n\n```ruby\nrequire 'firm'\n\na = [1, '2', :three, 4.321]\njson = a.serialize(format: :yaml)\nFIRM.deserialize(json, format: :yaml)\n```\n\nIRB output:\n\n```shell\n=\u003e true\n=\u003e \n[1,\n \"2\",\n :three,\n 4.321]\n=\u003e \"---\\n- 1\\n- '2'\\n- :three\\n- 4.321\\n\"\n=\u003e \n[1,\n \"2\",\n :three,\n 4.321]\n```\n\n### Serialize a user defined object\n\n```ruby\nrequire 'nokogiri' # enable XML output format\nrequire 'firm'\n\nclass Point\n\n  # define the class as serializable \n  include FIRM::Serializable\n\n  # declare the serializable properties of instances of this class\n  properties :x, :y\n\n  # allow instantiation using the default ctor (no args)\n  # (custom creation schemes can be defined)\n  def initialize(*args)\n    if args.empty?\n      @x = @y = 0\n    else\n      @x, @y = *args\n    end\n  end\n\n  # define the default getter/setter support FIRM will use when (de-)serializing properties\n  # (customization options are available)\n  attr_accessor :x, :y\n\nend\n\nrect = {topleft: Point.new(1,1), bottomright: Point.new(32, 64)}\nxml = rect.serialize(format: :xml)\n# all serializable classes provide the #deserialize class method\nHash.deserialize(xml, format: :xml)\n```\n\nIRB output:\n\n```shell\n=\u003e true\n=\u003e true\n=\u003e \n[:x,\n :x=,\n :y,\n :y=]\n=\u003e \n{:topleft=\u003e\n  #\u003cPoint:0x00007f6da9902518\n   @x=\n    1,\n   @y=\n    1\u003e,\n :bottomright=\u003e\n  #\u003cPoint:0x00007f6da9902450\n   @x=\n    32,\n   @y=\n    64\u003e}\n=\u003e \"\u003c?xml version=\\\"1.0\\\"?\u003e\\n\u003cHash\u003e\u003cP\u003e\u003cSymbol\u003etopleft\u003c/Symbol\u003e\u003cObject class=\\\"Point\\\"\u003e\u003cx\u003e\u003cInteger\u003e1\u003c/Integer\u003e\u003c/x\u003e\u003cy\u003e\u003cInteger\u003e1\u003c/Integer\u003e\u003c/y\u003e\u003c/Object\u003e\u003c/P\u003e\u003cP\u003e\u003cSymbol\u003ebottomright\u003c/Symbol\u003e\u003cObject class=\\\"Point\\\"\u003e\u003cx\u003e\u003cInteger\u003e32\u003c/Integer\u003e\u003c/x\u003e\u003cy\u003e\u003cInteger\u003e64\u003c/Integer\u003e\u003c/y\u003e\u003c/Object\u003e\u003c/P\u003e\u003c/Hash\u003e\\n\"\n=\u003e nil\n=\u003e \n{:topleft=\u003e\n  #\u003cPoint:0x00007f6da98f2208\n   @x=\n    1,\n   @y=\n    1\u003e,\n :bottomright=\u003e\n  #\u003cPoint:0x00007f6da98f0d90\n   @x=\n    32,\n   @y=\n    64\u003e}\n```\n\nSee [USAGE](USAGE.md) for more information.\n\n## FIRM licence\n\nFIRM is free and open-source. It is distributed under the liberal\nMIT licence which is compatible with both free and commercial development.\nSee [LICENSE](LICENSE) for more details.\n\n### Required Credits and Attribution\n\nFIRM requires no attribution, beyond retaining existing copyright notices.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcorino%2Ffirm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmcorino%2Ffirm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcorino%2Ffirm/lists"}