# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: 2026 ndaal Gesellschaft für Sicherheit in der Informationstechnik mbH & Co KG, Cologne
# SPDX-FileCopyrightText: Author: Pierre Gronau <Pierre.Gronau@ndaal.eu>

[package]
name = "sarif-viewer"
version = "0.1.4"
edition = "2021"
rust-version = "1.93"
description = "Offline viewer, validator and multi-format exporter for SARIF 2.1.0 and SARIF 2.2 (draft) — single binary, schema-validated import/export"
# Crate code is Apache-2.0; the embedded UI assets are Bootstrap / Bootstrap
# Icons (MIT) and the Roboto faces (OFL-1.1). The vendored OASIS SARIF schemas
# are redistributed under the OASIS IPR policy (no SPDX id) — see /license.
license = "Apache-2.0 AND MIT AND OFL-1.1"
repository = "https://gitlab.com/vPierre/ndaal_public_sarif_viewer"
homepage = "https://gitlab.com/vPierre/ndaal_public_sarif_viewer"
authors = ["Pierre Gronau <Pierre.Gronau@ndaal.eu>"]
readme = "README.md"
keywords = ["sarif", "static-analysis", "viewer", "security", "validation"]
categories = ["visualization", "command-line-utilities", "web-programming::http-server"]
# Package whitelist: only the sources, embedded assets and schemas the build
# needs — never the release/ binaries, fuzz/, test/ or documentation/ trees.
include = [
    "Cargo.toml",
    "README.md",
    "src/**",
    "schemas/*.json",
    "data/samples/minimal.sarif",
    "data/samples/nvulnlookup-clean.sarif",
]

[[bin]]
name = "sarif-viewer"
path = "src/main.rs"

# cargo-binstall: fetch the prebuilt binary from the GitLab Release assets of
# tag v{version} (uploaded via scripts/release_pipeline.sh / glab) instead of
# compiling from source. The download permalink resolves the asset by name. The
# default URL covers the triples we build for; the overrides map common host
# triples we do NOT ship (linux-gnu, windows-msvc) onto the musl / gnu / gnullvm
# binaries that run there. Without this block, binstall blindly guesses dozens
# of URLs and GitLab rate-limits (HTTP 429).
[package.metadata.binstall]
pkg-url = "{ repo }/-/releases/v{ version }/downloads/{ name }-{ version }-{ target }{ binary-ext }"
pkg-fmt = "bin"

[package.metadata.binstall.overrides.x86_64-unknown-linux-gnu]
pkg-url = "{ repo }/-/releases/v{ version }/downloads/{ name }-{ version }-x86_64-unknown-linux-musl"

[package.metadata.binstall.overrides.aarch64-unknown-linux-gnu]
pkg-url = "{ repo }/-/releases/v{ version }/downloads/{ name }-{ version }-aarch64-unknown-linux-musl"

[package.metadata.binstall.overrides.x86_64-pc-windows-msvc]
pkg-url = "{ repo }/-/releases/v{ version }/downloads/{ name }-{ version }-x86_64-pc-windows-gnu.exe"

[package.metadata.binstall.overrides.aarch64-pc-windows-msvc]
pkg-url = "{ repo }/-/releases/v{ version }/downloads/{ name }-{ version }-aarch64-pc-windows-gnullvm.exe"

[dependencies]
# Serialization / JSON document model (SARIF is JSON).
serde = { version = "1", features = ["derive"] }
serde_json = { version = "1", features = ["preserve_order"] }

# JSON-Schema validation against the bundled SARIF 2.1.0 (draft-04) and
# SARIF 2.2 (draft 2020-12) schemas — enforced on every import and export.
jsonschema = "0.46"

# Web server / router (reused from the ndaal OSCAL viewer).
bytes = "1"
http = "1"
http-body-util = "0.1"
hyper = { version = "1", features = ["http1", "server"] }
hyper-util = { version = "0.1", features = ["tokio", "server-auto", "http1"] }
matchit = "0.9"
tokio = { version = "1", features = ["rt-multi-thread", "macros", "net", "signal", "sync", "time"] }

# CLI.
clap = { version = "4", features = ["derive", "env"] }

# Multi-format export: lo_writer (pure-Rust libreoffice-rs) builds the
# document model and emits Markdown + ODT via save_as(); PDF is rendered
# directly (src/export_pdf.rs) with an embedded Roboto TrueType font via
# ttf-parser so Unicode survives.
lo_writer = "0.4.8"
lo_core = "0.4.8"
ttf-parser = { version = "0.25", default-features = false, features = ["std"] }

# Checksum sidecars (.sha-256 / .sha-512 / .sha3-512 / .blake3-512 / .shake256-512).
sha2 = "0.10"
sha3 = "0.10"
blake3 = "1.8.5"

# TLS 1.3 for HTTPS and QUIC, built on rustls with the aws-lc-rs crypto
# provider and `prefer-post-quantum`, so the X25519MLKEM768 post-quantum
# hybrid key-exchange group is offered first. TLS 1.3 only — the `tls12`
# default feature is intentionally off. The self-signed localhost certificate
# is minted at start-up via rcgen.
rustls = { version = "0.23", default-features = false, features = ["aws_lc_rs", "prefer-post-quantum", "logging", "std"] }
rcgen = "0.14"
tokio-rustls = { version = "0.26", default-features = false, features = ["logging", "aws_lc_rs"] }
time = "0.3"
# HTTP/3 over QUIC (UDP) on the same aws-lc-rs provider. h3 is pre-1.0 with an
# unstable API, so h3 / h3-quinn are pinned exactly to match the
# connection-handling code reused from ndaal csaf-crud.
quinn = { version = "0.11", default-features = false, features = ["runtime-tokio", "log", "rustls-aws-lc-rs"] }
h3 = "=0.0.8"
h3-quinn = "=0.0.10"

# Capability-scoped filesystem (path-traversal defence for import/export dirs).
cap-std = "4"

# Logging / errors.
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
anyhow = "1"

[dev-dependencies]
# Drive the router directly in integration tests (these types must match the
# library's, which cargo unifies to one version).
http = "1"
http-body-util = "0.1"
bytes = "1"
tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] }
tempfile = "3"
# Property-based testing: structured strategies with shrinking, complementing
# the byte-level cargo-fuzz targets. Runs under stable `cargo test`.
proptest = "1"

[profile.release]
lto = true
codegen-units = 1
strip = true
opt-level = 3

[lints.rust]
unsafe_code = "forbid"
unused_must_use = "deny"

[lints.clippy]
# Pedantic analysis on (warn), with the panicking-shortcut, unchecked-arithmetic
# and unchecked-indexing denials the security statement commits to.
pedantic = { level = "warn", priority = -1 }
nursery = { level = "warn", priority = -1 }
unwrap_used = "deny"
expect_used = "deny"
panic = "deny"
panic_in_result_fn = "deny"
unreachable = "deny"
todo = "deny"
unimplemented = "deny"
exit = "deny"
arithmetic_side_effects = "deny"
indexing_slicing = "deny"
# Casts where the tradeoff is accepted; transitive version splits we can't fix.
cast_possible_truncation = "allow"
cast_precision_loss = "allow"
cast_sign_loss = "allow"
cast_possible_wrap = "allow"
multiple_crate_versions = "allow"
module_name_repetitions = "allow"
missing_errors_doc = "allow"
missing_panics_doc = "allow"
must_use_candidate = "allow"
doc_markdown = "allow"
