cindermark 0.2.0

High-performance incremental Markdown parser with UTF-16 offsets, built for native text editors on Apple platforms
Documentation
[package]
name = "cindermark"
version = "0.2.0"
edition = "2021"
description = "High-performance incremental Markdown parser with UTF-16 offsets, built for native text editors on Apple platforms"
authors = ["Rene DeAnda <rene@deanda.org>"]
license = "MIT"
repository = "https://github.com/renedeanda/cindermark"
homepage = "https://embernotes.app"
readme = "README.md"
keywords = ["markdown", "parser", "incremental", "commonmark", "uniffi"]
categories = ["parser-implementations", "text-processing"]

# Build docs with the FFI surface enabled so the full API (including the Swift
# binding types) is documented on docs.rs, even though `ffi` is off by default.
[package.metadata.docs.rs]
features = ["ffi"]

[lib]
crate-type = ["staticlib", "cdylib", "lib"]
name = "cindermark"

[features]
# Pure-Rust parser by default. `cargo add cindermark` pulls exactly three
# crates — memchr, rustc-hash, unicode-segmentation — and no build-script
# codegen. Everything UniFFI-related is opt-in below.
default = []
# `ffi`: UniFFI scaffolding for the generated Swift / Apple bindings. Enabled
# automatically by build-apple.sh and the release workflow; Rust-only
# consumers never need it.
ffi = ["dep:uniffi"]
# `bindgen`: the `uniffi-bindgen` CLI that (re)generates the Swift bindings
# from cindermark.udl. Only the bundled `uniffi-bindgen` binary requires it,
# so the CLI toolchain (clap, goblin, …) never reaches a library consumer's
# dependency graph.
bindgen = ["ffi", "uniffi/cli"]
# `wasm`: wasm-bindgen surface for the browser demo (independent of `ffi`).
wasm = ["dep:wasm-bindgen"]

[dependencies]
# Optional and off by default — pulled in only by the `ffi` feature. The `cli`
# machinery lives behind `bindgen` (see above), keeping consumer builds lean.
uniffi = { version = "0.28", optional = true }
wasm-bindgen = { version = "0.2", optional = true }
memchr = "2"
rustc-hash = "2"
unicode-segmentation = "1"

[dev-dependencies]
criterion = { version = "0.5", features = ["html_reports"] }
proptest = "1"

[build-dependencies]
uniffi = { version = "0.28", features = ["build"] }

[profile.release]
# Production-grade tuning — this profile is what ships inside host apps
# (e.g. Ember Notes' App Store builds). Cargo's default release profile is
# opt-level=3 / codegen-units=16 / no LTO. These overrides take the parser
# the rest of the way:
#   - lto = "fat":           full link-time optimization across crates. ~10-20%
#                            runtime win on tight parser hot loops; produces a
#                            single inlined .a, smaller and faster.
#   - codegen-units = 1:     single codegen unit. Slower archive (~30s → ~2-3min
#                            for parser slice), tighter optimization, smaller
#                            binary. Acceptable since archives are infrequent.
#   - strip = true:          drop debug symbols. ~50% smaller .a (27 MB → ~12 MB),
#                            keeps the app binary slim. Crash logs lose Rust
#                            frame symbols; disable if you symbolicate them.
#   - panic = "unwind":      DELIBERATELY kept as the default. Skipping
#                            `panic = "abort"` preserves UniFFI's contract for
#                            converting Rust panics into Swift errors via
#                            `FfiConverterRustBuffer`. `abort` would terminate
#                            the host app on any parser panic instead of
#                            surfacing a recoverable Swift throw.
lto = "fat"
codegen-units = 1
strip = true

[profile.dev-optimized]
inherits = "release"
debug = 1
incremental = true
# Opt the local-dev profile OUT of the heavy release tuning so iterative
# `./build-apple.sh dev` rebuilds stay snappy. Without these overrides, the
# inheritance from `release` would also drag in LTO + codegen-units = 1
# and turn every local parser change into a 2-3 minute wait.
lto = false
codegen-units = 16
strip = false

[[bench]]
name = "parser_bench"
harness = false

[[bin]]
name = "uniffi-bindgen"
path = "uniffi-bindgen.rs"
# The binding generator needs the UniFFI CLI toolchain; `bindgen` pulls it in
# (and implies `ffi`). Library consumers never build this target.
required-features = ["bindgen"]

# wasm-pack's bundled wasm-opt crashes on this crate's output; rustc's own
# release profile (fat LTO, codegen-units=1) already does the heavy lifting.
[package.metadata.wasm-pack.profile.release]
wasm-opt = false