3 unstable releases
0.2.0 | Mar 15, 2024 |
---|---|
0.1.1 | Mar 7, 2024 |
0.1.0 | Jan 2, 2024 |
#16 in #pact
158 downloads per month
Used in pact-crypto
105KB
2K
SLoC
Macros for generating Rust types from TOML Pacts, and deriving Pact codecs for Rust types.
Generating Rust Types from TOML Pacts
The pact_toml
macro generates
Rust types from a string containing a Pact TOML:
# use pact_derive::pact_toml;
# use pact::codec::*;
// The string can be an anonymous constant like `_`;
// it will be fully replaced by the generated code.
#[pact_toml]
const _: &str = r#"
pact = "MyGreeter"
[data.1. Request]
message = 'string'
[data.2. Response]
message = 'string'
"#;
# fn main() {
// A unique struct will be generated for
// each data type in the pact.
let request = Request { message: "Hello!".into() };
// An enum will be generated with variants for
// each data type in the pact. The enum's name
// will be the pact's name, with `Data` appended.
let data = MyGreeterData::from(request);
assert_eq!("Hello!", match data {
MyGreeterData::Request(Request { message }) => message,
_ => unimplemented!(),
});
// The structs and enum have auto-generated pact codecs.
# let request = Request { message: "Hello!".into() };
# let data = MyGreeterData::from(request.clone());
let mut request_bytes = vec![];
request_bytes.write_data(&request).unwrap();
let mut data_bytes = vec![];
data_bytes.write_data(&data).unwrap();
assert_eq!(request_bytes, data_bytes);
// The enum can be used to safely decode
// bytes containing arbitrary pact data.
let data = MyGreeterData::decode_from(&mut data_bytes.as_slice()).unwrap();
assert_eq!("Hello!", match data {
MyGreeterData::Request(Request { message }) => message,
_ => unimplemented!(),
});
# }
Deriving Pact Entry Codecs for Rust Types
The derive(PactCodec)
macro derives
a pact codec (encoder and decoder) for a Rust struct:
# use pact_derive::PactCodec;
# use pact::codec::*;
# #[derive(Debug, Default, PartialEq)]
#[derive(PactCodec)]
struct MyRequest {
timestamp: u64,
message: String,
}
# fn main() {
let request = MyRequest {
message: "Hello!".into(),
timestamp: 1337,
};
// The struct can encode to and decode
// from pact-encoded data.
let mut request_bytes = vec![];
request_bytes.write_data(&request).unwrap();
let decoded_request = MyRequest::decode_from(&mut request_bytes.as_slice()).unwrap();
assert_eq!(request, decoded_request);
# }
If a struct represents a data type in a Pact,
an ordinal for the data type may be specified
by adding #[pact(ordinal = 96)]
to the struct,
where 96
is an example ordinal.
If a field is not Pact-encodable, or should
not be included during encoding or decoding,
it may be annotated with the #[pact(ignore = true)]
attribute.
License
Copyright 2024 Alicorn Systems, Inc.
Licensed under the GNU Affero General Public License version 3, as published by the Free Software Foundation. Refer to the license file for more information.
If you have any questions, please reach out to [hello@alicorn.systems
].
Dependencies
~4.5MB
~89K SLoC