mdns-sd-discovery 0.2.1

Async wrapper for native DNS-SD/mDNS service discovery
Documentation
# Contributing

Thanks for helping improve `mdns-sd-discovery`. This crate is an async Rust
wrapper over the operating system's native DNS-SD/mDNS service discovery
stack: the DNS-SD framework on macOS, the Win32 DNS-SD API on Windows, and
Avahi over D-Bus on Linux/FreeBSD.

## Development Setup

Install the Rust toolchain from `rust-toolchain.toml`:

```sh
rustup show
```

There are no native build dependencies on any platform — the Linux backend
talks to Avahi over D-Bus (via `zbus`), so not even the Avahi client headers
are needed. To *run* discovery on Linux, the Avahi daemon must be active on
the system.

## Local Commands

Build the project:

```sh
cargo build --locked
```

Run tests:

```sh
cargo test --locked
```

Check formatting:

```sh
cargo fmt -- --check
```

Run lint checks:

```sh
cargo clippy --locked --all-targets -- -D warnings
```

Browse services on the local network with the example:

```sh
cargo run --example discover-service
```

Note that each platform backend is `cfg`-gated, so a local build only checks
the backend for your OS; CI lints and tests all three.

## Fuzzing

The wire-format helpers (TXT record parsing and DNS name trimming) are
exercised by [`cargo-fuzz`] (libFuzzer) targets in `fuzz/`. They require a
nightly toolchain; the helper script installs `cargo-fuzz` if needed:

```sh
scripts/fuzz.sh            # run every target for 60s each
scripts/fuzz.sh 300        # 5 minutes per target
scripts/fuzz.sh 120 txt_roundtrip   # one target
```

Besides panic-safety, each target asserts semantic properties — a plain
"doesn't crash" oracle cannot see wrong-output bugs in record framing:

- `parse_txt_entry`: the `key[=value]` splitter checked against a
  straight-line spec; binary values must survive untouched.
- `parse_txt_buffer`: arbitrary bytes through the length-prefixed buffer
  parser; output must respect the framing limits.
- `txt_roundtrip`: entries encoded the way a responder would send them must
  decode back exactly — the guard against off-by-one framing bugs.
- `trim_dot`: trimming a fully-qualified name only ever removes trailing
  dots and is idempotent.

The targets reach the crate's internals through the `fuzzing` module in
`src/lib.rs`, which only exists when building with `--cfg fuzzing` (set
automatically by `cargo fuzz`).

CI runs a short soak on every push/PR and a longer one on a weekly schedule
(`.github/workflows/fuzz.yml`); any crash inputs are uploaded as artifacts.

[`cargo-fuzz`]: https://github.com/rust-fuzz/cargo-fuzz

## Project Layout

- `src/browse.rs`: the shared model — builders, events, errors, and the
  wire-format helpers.
- `src/linux/`, `src/macos/`, `src/windows/`: the `cfg`-gated platform
  backends, each exposing `browse_start` and `resolve_once`.
- `examples/`: runnable discovery examples.
- `fuzz/`: `cargo-fuzz` targets; `scripts/fuzz.sh`: the fuzz runner.
- `.github/workflows/`: CI, fuzzing, audit, analysis, and publish workflows.

## Contribution Guidelines

Keep changes focused and easy to review. Changes to the public API need doc
comments (`#![warn(missing_docs)]` is enforced) and should keep the three
backends behaviorally aligned. Update the README in the same pull request if
user-facing behavior changes.

Before opening a pull request, run:

```sh
cargo fmt -- --check
cargo clippy --locked --all-targets -- -D warnings
cargo test --locked
```

When reporting bugs, include:

- operating system and version
- crate version
- the discovery backend involved (Avahi / DNS-SD framework / Win32 API)
- a minimal code snippet reproducing the problem
- for Linux: whether `avahi-daemon` is running
- the full error output