v0.9.6
Headline: a built-in mock ONVIF device so downstream crates can unit-test
client code without a real camera — every vendor's ONVIF differs and depending
on a physical IP camera in tests is painful. Also rolls in the session-level
push subscribe and vendor-tolerant OSD parsing.
Added
- Built-in mock ONVIF device —
oxvif::mock(opt-in, behind features).
Stateful (Set persists, Get reflects it) and covers every operation oxvif
implements; state is in-memory (the library never writes to disk — opt into
persistence viaMockState::set_on_change).mockfeature →MockTransport, an in-processTransport(no sockets, no
axum) — the fast unit-test path:
OnvifClient::new("http://mock").with_transport(Arc::new(MockTransport::new())).mock-serverfeature →MockServer, a real axum HTTP server on an
ephemeral port (MockServer::start().await), shutting down on drop — for
cross-process / non-Rust clients.- Both default to no auth (call
.with_auth()/.enforce_auth(true)to
exercise WS-Security) and supportinject_fault(...)for error-path tests. axum/serdeare optional deps enabled only by these features — the
default build is unchanged and axum-free.- The
examples/mock_serverbinary is now a thin wrapper overMockServer
with TOML file persistence (--features mock-server); the mock engine moved
fromexamples/intosrc/mock/. Newtests/mock_workflow.rsdrives one
command from every service against a realMockServer.
OnvifSession::subscribe— delegates the WS-BaseNotification push
subscription that was previously only onOnvifClient.OsdOptions::max_per_text_type. NewHashMap<String, u32>
exposing the per-text-type quotas (Plain,Date,Time,
DateAndTime) some cameras advertise via XML attributes on
<MaximumNumberOfOSDs>(Genetec, recent Hikvision). Lets clients
pre-validateCreateOSDcalls against per-type limits instead of
parsing opaqueter:InvalidArgsfault strings after the fact.
Populated only when fetched viaOnvifSession::get_osd_options
—OnvifClient::get_osd_optionsleaves it empty (spec-strict).OnvifSession::get_osd_optionsnow layers vendor-extension
parsing on top of the spec-strictOnvifClientresult. Two
real-world shapes handled:<MaximumNumberOfOSDs Total="8" Plain="7" DateAndTime="1" .../>
— count fromTotalattribute when element body is empty, plus
per-type quotas from named attributes.<PositionOption>UpperLeft</PositionOption>flat siblings, when
the textbook nested-<Type>shape produces nothing.