Libraries
Installation and usage for each language
Overview
CAPNS has implementations in four languages. All follow the same specification and produce identical results for parsing, matching, and specificity scoring. The Rust implementation is the reference. Each language implementation is built on top of a Tagged URN library that handles the underlying URN format.
| Language | CAPNS library | Tagged URN library |
|---|---|---|
| Rust | capns | tagged-urn-rs |
| Go | capns-go | tagged-urn-go |
| JavaScript | capns-js | tagged-urn-js |
| Objective-C / Swift | capns-objc | tagged-urn-objc |
Rust (reference implementation)
Installation
# Cargo.toml [dependencies] capns = "0.1"
Parsing
use capns::CapUrn;
// Parse a capability URN
let urn = CapUrn::from_string("cap:in=\"media:pdf;bytes\";op=extract;out=\"media:text;utf8\"")?;
// Access tags
let op = urn.get_tag("op"); // Some("extract")
let in_spec = urn.in_spec(); // "media:pdf;bytes"
let out_spec = urn.out_spec(); // "media:text;utf8"
// Canonical string
let canonical = urn.to_string(); // tags sorted alphabetically
Matching
use capns::CapUrn;
let pattern = CapUrn::from_string("cap:in;op=extract;out")?;
let instance = CapUrn::from_string(
"cap:format=pdf;in=\"media:pdf;bytes\";op=extract;out=\"media:text;utf8\""
)?;
// Two equivalent ways to check:
assert!(pattern.accepts(&instance));
assert!(instance.conforms_to(&pattern));
// String convenience methods:
assert!(pattern.accepts_str("cap:in=\"media:pdf;bytes\";op=extract;out=\"media:text;utf8\""));
assert!(instance.conforms_to_str("cap:in;op=extract;out"));
Specificity
use capns::CapUrn;
let urn = CapUrn::from_string(
"cap:in=\"media:pdf;bytes\";op=extract;out=\"media:text;utf8\""
)?;
let score = urn.specificity(); // sum of tag scores
Go
Installation
go get github.com/filegrind/capns-go
Parsing
import "github.com/filegrind/capns-go"
// Parse a capability URN
urn, err := capns.CapUrnFromString("cap:in=\"media:pdf;bytes\";op=extract;out=\"media:text;utf8\"")
if err != nil {
log.Fatal(err)
}
// Access tags
op := urn.GetTag("op") // "extract"
inSpec := urn.InSpec() // "media:pdf;bytes"
outSpec := urn.OutSpec() // "media:text;utf8"
// Canonical string
canonical := urn.String()
Matching
pattern, _ := capns.CapUrnFromString("cap:in;op=extract;out")
instance, _ := capns.CapUrnFromString(
"cap:in=\"media:pdf;bytes\";op=extract;out=\"media:text;utf8\"",
)
// Two equivalent ways:
pattern.Accepts(instance) // true
instance.ConformsTo(pattern) // true
// String convenience methods:
pattern.AcceptsStr("cap:in=\"media:pdf;bytes\";op=extract;out=\"media:text;utf8\"")
instance.ConformsToStr("cap:in;op=extract;out")
Specificity
urn, _ := capns.CapUrnFromString(
"cap:in=\"media:pdf;bytes\";op=extract;out=\"media:text;utf8\"",
)
score := urn.Specificity()
JavaScript
Installation
npm install capns
Parsing
import { CapUrn } from 'capns';
// Parse a capability URN
const urn = CapUrn.fromString('cap:in="media:pdf;bytes";op=extract;out="media:text;utf8"');
// Access tags
const op = urn.getTag('op'); // 'extract'
const inSpec = urn.inSpec(); // 'media:pdf;bytes'
const outSpec = urn.outSpec(); // 'media:text;utf8'
// Canonical string
const canonical = urn.toString();
Matching
const pattern = CapUrn.fromString('cap:in;op=extract;out');
const instance = CapUrn.fromString(
'cap:in="media:pdf;bytes";op=extract;out="media:text;utf8"'
);
// Two equivalent ways:
pattern.accepts(instance); // true
instance.conformsTo(pattern); // true
Specificity
const urn = CapUrn.fromString(
'cap:in="media:pdf;bytes";op=extract;out="media:text;utf8"'
);
const score = urn.specificity();
Objective-C / Swift
Installation
Add capns-objc as a Swift Package Manager dependency.
// Package.swift
dependencies: [
.package(url: "https://github.com/filegrind/capns-objc.git", from: "0.1.0")
]
Swift usage
import CAPNSObjC
// Parse a capability URN
let urn = try CSCapUrn.fromString(
"cap:in=\"media:pdf;bytes\";op=extract;out=\"media:text;utf8\""
)
// Access tags
let op = urn.getTag("op") // "extract"
let inSpec = urn.inSpec() // "media:pdf;bytes"
let outSpec = urn.outSpec() // "media:text;utf8"
// Canonical string
let canonical = urn.toString()
Matching (Swift)
let pattern = try CSCapUrn.fromString("cap:in;op=extract;out")
let instance = try CSCapUrn.fromString(
"cap:in=\"media:pdf;bytes\";op=extract;out=\"media:text;utf8\""
)
// Two equivalent ways:
try pattern.accepts(instance) // true
try instance.conforms(to: pattern) // true
Objective-C usage
#import <CAPNSObjC/CAPNSObjC.h>
NSError *error = nil;
CSCapUrn *urn = [CSCapUrn fromString:@"cap:in=\"media:pdf;bytes\";op=extract;out=\"media:text;utf8\""
error:&error];
NSString *op = [urn getTag:@"op"]; // @"extract"
// Matching
BOOL match = [pattern accepts:instance error:&error];
BOOL conforms = [instance conformsTo:pattern error:&error];
Cross-Language Consistency
All four implementations are tested against the same set of test cases to ensure identical behavior. Given the same input URN strings, every implementation produces the same:
- Canonical string output
- Matching results (accepts/conformsTo)
- Specificity scores
- Parse errors (same error codes across languages)
If you find a case where two implementations disagree, that's a bug. Report it on the relevant GitHub repository.