wip_http/lib.rs
1//! Framework-independent standard WIP over HTTP v1 binding.
2//!
3//! This crate owns endpoint and route derivation, UTF-8 JSON encoding, canonical
4//! success and error response handling, HTTP status mapping, descriptor-guided
5//! operation-value conversion. It deliberately performs no I/O and depends on no
6//! server framework, TLS implementation, filesystem projection, client cache, or
7//! presentation layer. URL schemes, TLS, certificates, authentication mechanisms,
8//! proxies, and caches are selected by the HTTP implementation and deployment
9//! rather than by WIP conformance.
10//!
11//! Logical values remain owned by [`wip_protocol`]. Validators and `Bytes` are
12//! encoded in JSON bodies using canonical RFC 4648 Section 4 base64; this crate
13//! does not infer WIP validator semantics from `ETag` or `If-Match`.
14//!
15//! Interface references use exact JSON objects with required `scope` and `name`
16//! strings in every position. Legacy strings and display shorthand are rejected.
17//! Scope is a canonical absolute Worldspace path, not an HTTP endpoint prefix.
18//! Optional `scope_ref` metadata on fetch responses and call interface targets is
19//! an opaque string, never base64; absent fields are omitted and null is rejected.
20//! Call metadata validates reference shape without resolving scope ancestry or
21//! identity, which remain Host checks with `InterfaceMismatch` precedence.
22//!
23//! ```
24//! use wip_http::{Endpoint, Limits, encode_observe_request};
25//! use wip_protocol::ObserveRequest;
26//!
27//! let endpoint = Endpoint::parse("http://example.test/api/wip")?;
28//! let limits = Limits::new(64 * 1024, 1024 * 1024, 64)?;
29//! let request = encode_observe_request(
30//! &endpoint,
31//! &ObserveRequest { path: "/items/123".into(), depth: 0 },
32//! limits,
33//! )?;
34//! assert_eq!(request.uri(), "http://example.test/api/wip/v1/observe");
35//! assert_eq!(request.method(), http::Method::POST);
36//! # Ok::<(), Box<dyn std::error::Error>>(())
37//! ```
38
39#![deny(missing_docs)]
40
41mod codec;
42mod endpoint;
43mod error;
44mod json;
45mod response;
46
47pub use codec::{
48 CallOperationMetadata, EncodeHttpError, RequestMetadataError, decode_call_operation_metadata,
49 decode_call_operation_request, decode_call_operation_response, decode_fetch_interface_request,
50 decode_fetch_interface_response, decode_observe_request, decode_observe_response,
51 encode_call_operation_request, encode_call_operation_response, encode_fetch_interface_request,
52 encode_fetch_interface_response, encode_observe_request, encode_observe_response,
53 encode_protocol_error_response, is_json_content_type, validate_http_request,
54};
55pub use endpoint::{Endpoint, EndpointError, JSON_CONTENT_TYPE, Route};
56pub use error::{BodyKind, CodecError, LimitConfigurationError, Limits};
57pub use response::{
58 ClientResponseError, DecodedResponse, InvalidResponseKind, StatusMismatch,
59 TransportBindingFailure, TransportFailureKind, error_code_name, status_for_error,
60};
61
62/// Framework-neutral HTTP types used by this binding's public API.
63pub use http;
64/// URL type used by [`Endpoint`].
65pub use url;
66/// Transport-independent logical protocol model used by this binding.
67pub use wip_protocol;