bcur 1.0.0

A Rust implementation of Uniform Resources
Documentation
# bcur

A Rust implementation of [Uniform Resources](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md) (URs).

URs encode binary payloads as URI-friendly strings for QR codes and unreliable channels, using [bytewords](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-012-bytewords.md) and fountain codes for multi-part transfer.

## Status (1.0)

Transport: bytewords + fountain + multi-part UR + frozen `DecoderLimits` Default.  
Typed dCBOR: `feature = "dcbor"` (`Ur`, traits, multipart wrappers; implies `std`).

## Layering

**L0–L3 (always built).** A UR type token is a validated label (`[a-z0-9-]+` after ASCII lowercasing). The body is raw bytes plus bytewords CRC. `ur::encode` / `ur::Encoder` do **not** parse or require CBOR. `UrType::bytes()` and `Encoder::bytes` exist so tests and generic hosts can move untyped payloads. This is an intentional split, not an accident, and it matches ur-rs.

**BCR-2020-005** says a UR *message* MUST be dCBOR and that type `bytes` MUST NOT be used except for testing. That MUST is enforced on **L4** (`feature = "dcbor"`): `typed::Ur::from_ur_string` and `MultipartDecoder::message` reject non-dCBOR (`Error::Cbor`). L4 also uses the first registered `dcbor` tag **name** as the type token and strips the tag from the UR body (005 "top-level UR is untagged").

**This crate will not** grow a Blockchain Commons type registry, Envelope, or PSBT module to "satisfy 005." Application types belong in a consumer crate that implements `UrEncodable` / `UrDecodable`.

## Features

| Feature | Default | Description |
| --------- | --------- | ------------- |
| `std` | yes | Host / std builds |
| `dcbor` | no | Typed `Ur` / traits / multipart wrappers (implies `std`) |

`no_std` + `alloc`: `--no-default-features`.

## Quick start

L3 transport — opaque bytes plus a type token. `Encoder::bytes` / `UrType::bytes`
remain for tests and generic hosts; they are not the product default.

```rust
use bcur::{Decoder, Encoder, UrType};

let data = b"Ten chars!".repeat(10);
let mut encoder = Encoder::new(&data, 5, &UrType::new("alpha").unwrap()).unwrap();
let mut decoder = Decoder::default();
while !decoder.complete() {
    decoder.receive(&encoder.next_part().unwrap()).unwrap();
}
assert_eq!(decoder.message().unwrap().as_deref(), Some(data.as_slice()));
```

L4 typed dCBOR (`feature = "dcbor"`). First registered tag **name** is the UR
type; the body is untagged.

```rust
use bcur::Ur;

let ur = Ur::new("test", vec![1, 2, 3]).unwrap();
assert_eq!(ur.string(), "ur:test/lsadaoaxjygonesw");
```

## License

MIT OR Apache-2.0