Skip to content

Releases: TeamMilestone/tsip_parser_gem

v0.2.3 — Address.new 0-arg allocator

Choose a tag to compare

@team-milestone-alfonso team-milestone-alfonso released this 19 Apr 10:50

Gem-only release per docs/V0_2_3_HANDOFF.md. No crate change — tsip-parser = \"0.2\" unchanged.

What changed

Previously TsipParser::Address.new raised TypeError: allocator undefined for TsipParser::Address because the magnus::wrap macro does not register a Ruby allocator. This release registers a 0-arg new singleton method that returns an empty Address (display_name: nil, uri: nil, params: {}), then the existing Ruby-side setters assemble it:

a = TsipParser::Address.new
a.display_name = \"Alice\"
a.uri          = TsipParser::Uri.parse(\"sip:alice@example.com\")
a.params[\"tag\"] = \"xyz\"
a.to_s  # => \"\\\"Alice\\\" <sip:alice@example.com>;tag=xyz\"

Unblocks the tsip-core bridge Address.build helper to drop its placeholder-parse workaround (parse(\"<sip:_@_>\")), which at 8k cps dialog throughput costs ~16k unnecessary parses/s.

Tests

41 runs / 72 assertions / 0 failures — 39 existing + 2 new.

Install

gem install tsip_parser

RubyGems: https://rubygems.org/gems/tsip_parser/versions/0.2.3

v0.2.2 — tsip-core class-alias surface

Choose a tag to compare

@team-milestone-alfonso team-milestone-alfonso released this 19 Apr 10:05

Gem-only release per docs/V0_2_2_HANDOFF.md. No crate change — tsip-parser = \"0.2\" still resolves to 0.2.1.

What changed

Exposes three crate class methods that tsip-core needs to replace its per-parse bridge shim with a direct TsipCore::Sip::Uri = TsipParser::Uri class alias. Closes the −2.8% throughput regression measured in the tsip-core integration bench on 2026-04-19.

  • TsipParser::Uri.parse_range(str, from, to) — byte-range parse. tsip-core's Address.parse uses this to parse the URI inside <...> without substring alloc. Offsets are validated + must land on UTF-8 char boundaries; raises ParseError otherwise.
  • TsipParser::Uri.parse_param(raw, hash) — writes one key[=value] segment into an existing Ruby Hash. Used by tsip-core Via.parse on each semicolon-split segment. Key-only segments insert \"\"; empty raw is a no-op; duplicate keys overwrite.
  • TsipParser::Uri.parse_host_port(str) — returns [host, port_or_nil]. IPv6 bracket form ([::1]:5060) supported.

Not added (per HANDOFF §3.3)

Address.new(display_name:, uri:, params:) kwargs constructor. tsip-core is adding an Address.build(...) helper on its side instead.

Tests

39 runs / 67 assertions / 0 failures — 25 existing + 14 new class-method tests.

Install

gem install tsip_parser

RubyGems: https://rubygems.org/gems/tsip_parser/versions/0.2.2

v0.2.1 — Escape parity with crate Display

Choose a tag to compare

@team-milestone-alfonso team-milestone-alfonso released this 19 Apr 09:52

Tracks upstream tsip-parser 0.2.1.

What changed

Accepts URI-level param keys/values containing ; ? & = < >. Round-trip stability comes from render-side pct-escape (lowercase hex). Closes the last xoracle parity case (sip:alice@host;<evil>=1) vs the Ruby tsip-core reference.

Gem-side fix (behavioral)

Previously the Ruby serialization path — triggered once params or headers was touched — wrote fields literally, diverging from the Rust Display for inputs with @ : ; ? < > % & = or whitespace. Now Uri#append_to mirrors the crate's escape set so fast-path and slow-path produce identical output.

Performance

M1 macOS, Ruby 4.0.1, release build:

endpoint tsip_parser tsip-core speedup
Uri.parse 646k ips 41k ips 15.8×
Address.parse 694k ips 41k ips 16.8×

Escape runs only on the mutation-touched slow path, so parse throughput is unchanged from 0.2.0.

Upgrade notes

Drop-in. If you had rescue TsipParser::ParseError catching inputs with > in params, those now parse — audit and simplify.

Install

gem install tsip_parser

RubyGems: https://rubygems.org/gems/tsip_parser/versions/0.2.1

v0.2.0 — Track crate 0.2.0

Choose a tag to compare

@team-milestone-alfonso team-milestone-alfonso released this 19 Apr 08:48

Tracks upstream tsip-parser 0.2.0.

What changed

Behavior, not API. The Ruby surface (TsipParser::Uri, ::Address, ParseError, helper methods) is identical to 0.1.0. What moved is the accepted-input set:

  • Accepts pct-encoded userinfo specials.
  • Accepts < in param keys.
  • Accepts leading/trailing whitespace in URI-level param/header values.
  • Round-trip stability is preserved via render-side pct-escape — pct-decoded fields (userinfo, URI header key/value) are pct-escaped when to_s serializes.

Narrow parse-time rejections still remain for bytes that literal param storage cannot round-trip: > in any param, ? in URI-level params.

Performance

M1 macOS, Ruby 4.0.1, release build:

endpoint tsip_parser tsip-core speedup
Uri.parse 654k ips 41k ips 16.1×
Address.parse 695k ips 41k ips 16.8×

Slightly faster than 0.1.0 (permissive parse skips validation work).

Upgrade notes

Drop-in. If your code depended on InvalidHost being raised for previously-rejected inputs, those will now parse — audit any call sites that did rescue TsipParser::ParseError expecting that specific behavior.

Install

gem install tsip_parser

RubyGems: https://rubygems.org/gems/tsip_parser/versions/0.2.0

v0.1.0 — Initial release

Choose a tag to compare

@team-milestone-alfonso team-milestone-alfonso released this 19 Apr 06:56

First published release. Thin Ruby binding over the tsip-parser Rust crate (pinned to ~> 0.1, resolves to 0.1.1).

Features

  • TsipParser::Uri.parse(str) — RFC 3261 §19.1 SIP / SIPS / tel URI parser
  • TsipParser::Address.parse(str) — RFC 3261 §25.1 name-addr / addr-spec
  • TsipParser::ParseError (subclass of ArgumentError) — tsip-core-compatible error path
  • Uri.parse_many / Address.parse_many — batch FFI
  • uri.param(k) / uri.header(k) / address.param(k) — direct Vec lookup, no Hash materialization
  • Params / headers memoized on the Ruby side so uri.params["t"] = "tls" round-trips through to_s correctly

Performance

M1 macOS, Ruby 4.0.1, release build:

endpoint tsip_parser tsip-core speedup
Uri.parse 595k ips 40k ips 14.8×
Address.parse 672k ips 41k ips 16.6×

Clears the 10× target from the project's HANDOVER doc.

Install

gem install tsip_parser

RubyGems: https://rubygems.org/gems/tsip_parser/versions/0.1.0