milter-callback 0.1.1

Attribute macros for milter callback generation
Documentation

Procedural macros to generate C callback functions and a thin wrapping layer.

Callback results

The result type may be wrapped in a milter::Result where desired. This is a convenience as most Context methods return milter::Results these can then be propagated with the ? operator.

For example, the end-of-message handler may return plain Status:

# #[macro_use] extern crate milter_callback;
# use milter::{ActionContext, Status};
#[on_eom(eom_callback)]
fn handle_eom(context: ActionContext<()>) -> Status {
Status::Continue
}

Or it may return milter::Result<Status>. The example shows use of the ? operator enabled by choosing this return type.

# #[macro_use] extern crate milter_callback;
# use milter::{ActionContext, Status};
#[on_eom(eom_callback)]
fn handle_eom(context: ActionContext<()>) -> milter::Result<Status> {
if let Some(version) = context.macro_value("v")? {
println!("{}", version);
}

Ok(Status::Continue)
}

This feature is supported on all the callback functions.

Errors

An error result returned from a callback leads to a Status::Tempfail response returned to the MTA. The milter will continue processing.

Panicking leads to shutdown of the milter. That is, Milter::run returns. It could then be restarted by invoking Milter::run again. However, restarting is potentially hazardous as panic exits without going through potential cleanup paths in close or abort. That is, there is a possibility of memory leakage.

Returning an error result does not have this problem. Returning an error leads to tempfail and then the ordinary cleanup path on connection close.