cap:
Browse Sign In

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.

LanguageCAPNS libraryTagged 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.