Skip to content

Commit

Permalink
docs(ffi): generate FFI documentation (#2447)
Browse files Browse the repository at this point in the history
  • Loading branch information
seanmonstar authored Feb 27, 2021
1 parent 4c946af commit f162ca2
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -179,4 +179,4 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: rustdoc
args: --features full -- --cfg docsrs -D broken-intra-doc-links
args: --features full,ffi -- --cfg docsrs --cfg hyper_unstable_ffi -D broken-intra-doc-links
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ nightly = []
__internal_happy_eyeballs_tests = []

[package.metadata.docs.rs]
features = ["full"]
rustdoc-args = ["--cfg", "docsrs"]
features = ["ffi", "full"]
rustdoc-args = ["--cfg", "docsrs", "--cfg", "hyper_unstable_ffi"]

[package.metadata.playground]
features = ["full"]
Expand Down
2 changes: 2 additions & 0 deletions src/ffi/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ use super::task::{hyper_context, hyper_task, hyper_task_return_type, AsTaskType}
use super::{UserDataPointer, HYPER_ITER_CONTINUE};
use crate::body::{Body, Bytes, HttpBody as _};

/// A streaming HTTP body.
pub struct hyper_body(pub(super) Body);

/// A buffer of bytes that is sent or received on a `hyper_body`.
pub struct hyper_buf(pub(super) Bytes);

pub(crate) struct UserBody {
Expand Down
6 changes: 6 additions & 0 deletions src/ffi/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,18 @@ use super::http_types::{hyper_request, hyper_response};
use super::io::hyper_io;
use super::task::{hyper_executor, hyper_task, hyper_task_return_type, AsTaskType, WeakExec};

/// An options builder to configure an HTTP client connection.
pub struct hyper_clientconn_options {
builder: conn::Builder,
/// Use a `Weak` to prevent cycles.
exec: WeakExec,
}

/// An HTTP client connection handle.
///
/// These are used to send a request on a single connection. It's possible to
/// send multiple requests on a single connection, such as when HTTP/1
/// keep-alive or HTTP/2 is used.
pub struct hyper_clientconn {
tx: conn::SendRequest<crate::Body>,
}
Expand Down
2 changes: 2 additions & 0 deletions src/ffi/error.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use libc::size_t;

/// A more detailed error object returned by some hyper functions.
pub struct hyper_error(crate::Error);

/// A return code for many of hyper's methods.
#[repr(C)]
pub enum hyper_code {
/// All is well.
Expand Down
5 changes: 5 additions & 0 deletions src/ffi/http_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ use super::HYPER_ITER_CONTINUE;
use crate::header::{HeaderName, HeaderValue};
use crate::{Body, HeaderMap, Method, Request, Response, Uri};

/// An HTTP request.
pub struct hyper_request(pub(super) Request<Body>);

/// An HTTP response.
pub struct hyper_response(pub(super) Response<Body>);

/// An HTTP header map.
///
/// These can be part of a request or response.
#[derive(Default)]
pub struct hyper_headers {
pub(super) headers: HeaderMap,
Expand Down
5 changes: 5 additions & 0 deletions src/ffi/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,19 @@ use tokio::io::{AsyncRead, AsyncWrite};

use super::task::hyper_context;

/// Sentinal value to return from a read or write callback that the operation
/// is pending.
pub const HYPER_IO_PENDING: size_t = 0xFFFFFFFF;
/// Sentinal value to return from a read or write callback that the operation
/// has errored.
pub const HYPER_IO_ERROR: size_t = 0xFFFFFFFE;

type hyper_io_read_callback =
extern "C" fn(*mut c_void, *mut hyper_context<'_>, *mut u8, size_t) -> size_t;
type hyper_io_write_callback =
extern "C" fn(*mut c_void, *mut hyper_context<'_>, *const u8, size_t) -> size_t;

/// An IO object used to represent a socket or similar concept.
pub struct hyper_io {
read: hyper_io_read_callback,
write: hyper_io_write_callback,
Expand Down
38 changes: 38 additions & 0 deletions src/ffi/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,33 @@
// We have a lot of c-types in here, stop warning about their names!
#![allow(non_camel_case_types)]
// fmt::Debug isn't helpful on FFI types
#![allow(missing_debug_implementations)]
// unreachable_pub warns `#[no_mangle] pub extern fn` in private mod.
#![allow(unreachable_pub)]

//! # hyper C API
//!
//! This part of the documentation describes the C API for hyper. That is, how
//! to *use* the hyper library in C code. This is **not** a regular Rust
//! module, and thus it is not accessible in Rust.
//!
//! ## Unstable
//!
//! The C API of hyper is currently **unstable**, which means it's not part of
//! the semver contract as the rest of the Rust API is. Because of that, it's
//! only accessible if `--cfg hyper_unstable_ffi` is passed to `rustc` when
//! compiling. The easiest way to do that is setting the `RUSTFLAGS`
//! environment variable.
//!
//! ## Building
//!
//! The C API is part of the Rust library, but isn't compiled by default. Using
//! `cargo`, it can be compiled with the following command:
//!
//! ```notrust
//! RUSTFLAGS="--cfg hyper_unstable_ffi" cargo build --features client,http1,http2,ffi
//! ```
// We may eventually allow the FFI to be enabled without `client` or `http1`,
// that is why we don't auto enable them as `ffi = ["client", "http1"]` in
// the `Cargo.toml`.
Expand All @@ -29,16 +54,29 @@ mod http_types;
mod io;
mod task;

pub use self::body::*;
pub use self::client::*;
pub use self::error::*;
pub use self::http_types::*;
pub use self::io::*;
pub use self::task::*;

pub(crate) use self::body::UserBody;
pub(crate) use self::http_types::{HeaderCaseMap, ReasonPhrase};

/// Return in iter functions to continue iterating.
pub const HYPER_ITER_CONTINUE: libc::c_int = 0;
/// Return in iter functions to stop iterating.
#[allow(unused)]
pub const HYPER_ITER_BREAK: libc::c_int = 1;

/// An HTTP Version that is unspecified.
pub const HYPER_HTTP_VERSION_NONE: libc::c_int = 0;
/// The HTTP/1.0 version.
pub const HYPER_HTTP_VERSION_1_0: libc::c_int = 10;
/// The HTTP/1.1 version.
pub const HYPER_HTTP_VERSION_1_1: libc::c_int = 11;
/// The HTTP/2 version.
pub const HYPER_HTTP_VERSION_2: libc::c_int = 20;

struct UserDataPointer(*mut std::ffi::c_void);
Expand Down
11 changes: 11 additions & 0 deletions src/ffi/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,17 @@ use super::UserDataPointer;
type BoxFuture<T> = Pin<Box<dyn Future<Output = T> + Send>>;
type BoxAny = Box<dyn AsTaskType + Send + Sync>;

/// Return in a poll function to indicate it was ready.
pub const HYPER_POLL_READY: c_int = 0;
/// Return in a poll function to indicate it is still pending.
///
/// The passed in `hyper_waker` should be registered to wake up the task at
/// some later point.
pub const HYPER_POLL_PENDING: c_int = 1;
/// Return in a poll function indicate an error.
pub const HYPER_POLL_ERROR: c_int = 3;

/// A task executor for `hyper_task`s.
pub struct hyper_executor {
/// The executor of all task futures.
///
Expand All @@ -47,6 +54,7 @@ pub(crate) struct WeakExec(Weak<hyper_executor>);

struct ExecWaker(AtomicBool);

/// An async task.
pub struct hyper_task {
future: BoxFuture<BoxAny>,
output: Option<BoxAny>,
Expand All @@ -57,12 +65,15 @@ struct TaskFuture {
task: Option<Box<hyper_task>>,
}

/// An async context for a task that contains the related waker.
pub struct hyper_context<'a>(Context<'a>);

/// A waker that is saved and used to waken a pending task.
pub struct hyper_waker {
waker: std::task::Waker,
}

/// A descriptor for what type a `hyper_task` value is.
#[repr(C)]
pub enum hyper_task_return_type {
/// The value of this task is null (does not imply an error).
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ pub mod service;
pub mod upgrade;

#[cfg(feature = "ffi")]
mod ffi;
pub mod ffi;

cfg_proto! {
mod headers;
Expand Down

0 comments on commit f162ca2

Please sign in to comment.