[package]
name = "epics-bridge-rs"
version.workspace = true
edition.workspace = true
description = "EPICS protocol bridges: Record↔PVA (QSRV), CA gateway, pvalink, PVA gateway"
license-file = "LICENSE"
authors.workspace = true
repository.workspace = true

[features]
default = ["qsrv", "qsrv-bin", "ca-gateway", "ca-gateway-bin"]
# Record ↔ pvAccess channels (C++ QSRV equivalent)
qsrv = [
    "dep:epics-pva-rs",
    "dep:epics-ca-rs",
    "dep:serde",
    "dep:serde_json",
]
# QSRV daemon binary (qsrv-rs)
qsrv-bin = ["qsrv", "dep:clap", "dep:tracing-subscriber"]
# CA fan-out gateway (C++ ca-gateway equivalent)
ca-gateway = ["dep:epics-ca-rs", "dep:regex"]
# CA gateway daemon binary (ca-gateway-rs)
ca-gateway-bin = ["ca-gateway", "dep:clap", "dep:tracing-subscriber"]
# CA gateway with TLS termination on the downstream side. Clients
# present certificates to the gateway, the gateway forwards plaintext
# (or TLS, see upstream side) to the upstream IOC. Layered on the
# `experimental-rust-tls` feature in epics-ca-rs — read its caveats
# in epics-ca-rs/doc/11-tls-design.md before enabling.
ca-gateway-tls = [
    "ca-gateway",
    "ca-gateway-bin",
    "epics-ca-rs/experimental-rust-tls",
]
# PVA links for record INP/OUT (planned)
pvalink = ["dep:epics-pva-rs"]
# PVA-to-PVA proxy — mirrors C++ pva2pva/p2pApp.
pva-gateway = ["dep:epics-pva-rs", "dep:regex"]
# PVA gateway daemon binary (pva-gateway-rs).
pva-gateway-bin = ["pva-gateway", "dep:clap", "dep:tracing-subscriber"]
# Convenience: enable all bridges + binaries
all-bridges = ["qsrv", "qsrv-bin", "ca-gateway", "ca-gateway-bin", "pvalink", "pva-gateway", "pva-gateway-bin", "dual-gateway", "dual-gateway-bin"]
# Dual-protocol IOC: serves the same PV database over both CA and PVA
# from a single process. Drops in for sites whose tooling mix is
# transitioning to PVA.
dual-ioc = ["dep:epics-pva-rs", "dep:epics-ca-rs"]
dual-ioc-bin = ["dual-ioc", "dep:clap", "dep:tracing-subscriber"]
# Dual-protocol gateway: single binary that runs the CA gateway and
# the PVA gateway side by side as independent supervisors. Useful for
# ops teams that want one process to manage instead of two. Each
# gateway proxies its own protocol — no cross-protocol bridging.
dual-gateway = ["ca-gateway", "pva-gateway"]
dual-gateway-bin = [
    "dual-gateway",
    "ca-gateway-bin",
    "pva-gateway-bin",
    "dep:serde",
    "dep:toml",
]

[dependencies]
epics-base-rs = { workspace = true }
tokio = { version = "1", features = ["full"] }
# Refcounted byte buffer for the raw-frame fan-out path (F-G12).
bytes = "1"
thiserror = "2"
chrono = "0.4"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"], optional = true }

# Feature-gated optional dependencies
epics-pva-rs = { workspace = true, optional = true }
epics-ca-rs = { workspace = true, optional = true }
serde = { version = "1", features = ["derive"], optional = true }
serde_json = { version = "1", optional = true }
parking_lot = "0.12"
arc-swap = "1"
regex = { version = "1", optional = true }
clap = { version = "4", features = ["derive"], optional = true }
toml = { version = "0.8", optional = true }

[[bin]]
name = "ca-gateway-rs"
path = "src/bin/ca_gateway_rs.rs"
required-features = ["ca-gateway-bin"]

[[bin]]
name = "qsrv-rs"
path = "src/bin/qsrv_rs.rs"
required-features = ["qsrv-bin"]

[[bin]]
name = "dual-ioc-rs"
path = "src/bin/dual_ioc_rs.rs"
required-features = ["dual-ioc-bin"]

[[bin]]
name = "pva-gateway-rs"
path = "src/bin/pva_gateway_rs.rs"
required-features = ["pva-gateway-bin"]

[[bin]]
name = "dual-gateway-rs"
path = "src/bin/dual_gateway_rs.rs"
required-features = ["dual-gateway-bin"]

[dev-dependencies]
serial_test = "3"
