summaryrefslogtreecommitdiffstats
path: root/openpgp-ffi/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'openpgp-ffi/src/lib.rs')
-rw-r--r--openpgp-ffi/src/lib.rs118
1 files changed, 118 insertions, 0 deletions
diff --git a/openpgp-ffi/src/lib.rs b/openpgp-ffi/src/lib.rs
new file mode 100644
index 00000000..40233a37
--- /dev/null
+++ b/openpgp-ffi/src/lib.rs
@@ -0,0 +1,118 @@
+//! Provides a Foreign Function Interface.
+//!
+//! We provide a set of functions that use C types and the C calling
+//! convention. This interfaces allows you to use Sequoia safely from
+//! any other language.
+//!
+//! # Guarantees
+//!
+//! Provided that the caller obeys her side of the contract, this
+//! library...
+//!
+//! - will not make an invalid memory access,
+//! - will not `abort(2)`,
+//! - XXX
+//!
+//! # Types
+//!
+//! Sequoia objects are opaque objects. They are created in
+//! constructors, and must be freed when no longer needed.
+//!
+//! Pointers handed to Sequoia must not be `NULL`, unless explicitly
+//! stated. See [references].
+//!
+//! [references]: #references
+//!
+//! Enumeration-like values must be in the valid range.
+//!
+//! Strings must be UTF-8 encoded and zero-terminated. Malformed
+//! characters will be substituted, and the result is likely not what
+//! you expect.
+//!
+//! # Ownership
+//!
+//! When ownership of a `T` is transferred across the FFI boundary, a
+//! `*mut T` is used.
+//!
+//! To transfer ownership from Rust to C, we box the Rust object, and
+//! use [`Box::into_raw(..)`]. From this moment on, ownership must be
+//! managed by the C application.
+//!
+//! [`Box::into_raw(..)`]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.into_raw
+//!
+//! To transfer ownership from C to Rust, we re-create the box using
+//! [`Box::from_raw(..)`].
+//!
+//! [`Box::from_raw(..)`]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.from_raw
+//!
+//! In this crate we use a series of macros to transfer ownership from
+//! Rust to C. `fry_box` matches on `Result<T>`, handling errors by
+//! terminating the current function, returning the error using the
+//! context. `maybe_box_raw` matches on `Option<T>`, turning `None`
+//! into `NULL`. Finally, `box_raw` is merely a shortcut for
+//! `Box::into_raw(Box::new(..))`.
+//!
+//! # References
+//!
+//! When references are transferred across the FFI boundary, we use
+//! `*const T`, or `*mut T`. If the parameter is optional, a
+//! `Option<&T>` or `Option<&mut T>` is used.
+//!
+//! Application code must adhere to Rust's reference rules:
+//!
+//! - Either one mutable reference or any number of immutable ones.
+//! - All references are non-`NULL`.
+//! - All references are valid.
+//!
+//! In this crate we enforce the second rule by asserting that all
+//! pointers handed in are non-`NULL`. If a parameter of an FFI
+//! function uses `Option<&T>` or `Option<&mut T>`, it may be called
+//! with `NULL`. A notable example are the destructors (`sq_*_free`).
+//!
+//! # Lifetimes
+//!
+//! If you derive a complex object from another complex object, you
+//! must assume that the original object is borrowed by the resulting
+//! object unless explicitly stated otherwise. For example, objects
+//! created using a context must not outlive that context. Similarly,
+//! iterators must not outlive the object they are created from.
+//!
+//! Failing to adhere to lifetime restrictions results in undefined
+//! behavior.
+//!
+//! # Error handling
+//!
+//! Sequoia will panic if you provide bad arguments, e.g. hand a
+//! `NULL` pointer to a function that does not explicitly allow this.
+//!
+//! Failing functions return `NULL`. Functions that require a
+//! `Context` return complex errors. Complex errors are stored in the
+//! `Context`, and can be retrieved using `sq_last_strerror`.
+//!
+//! # Example
+//!
+//! ```c
+//! #include <sequoia/openpgp.h>
+//! #include <error.h>
+//!
+//! sq_error_t err;
+//! sq_tpk_t tpk;
+//!
+//! tpk = sq_tpk_from_file (&err, "../openpgp/tests/data/keys/testy.pgp");
+//! if (tpk == NULL)
+//! error (1, 0, "sq_tpk_from_bytes: %s", sq_error_string (err));
+//!
+//! sq_tpk_free (tpk);
+//! ```
+
+#![warn(missing_docs)]
+
+extern crate failure;
+#[macro_use]
+extern crate lazy_static;
+extern crate libc;
+
+extern crate sequoia_ffi_macros;
+use sequoia_ffi_macros::ffi_catch_abort;
+
+include!("common.rs");