blob: 55d8d62906673762b4a1565d2d4cdfe14086472f [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use fuchsia_zircon as zx;
#[cxx::bridge(namespace = rust::zx::ffi)]
pub mod ffi {
/// A valueless result type, similar to C++ zx::status<> but with an added string message to
/// hold the string-ified Rust error. On the C++ side this can be converted to a
/// rust::zx::Result which has a similar API to zx::status (see //src/lib/fuchsia-cxx/result.h).
///
/// This type can be reused in your own bridges directly or used to create result types with a
/// success value. For example:
///
/// #[cxx::bridge(namespace = foo::ffi)]
/// mod ffi {
/// #[namespace = "rust::zx::ffi"]
/// extern "C++" {
/// include!("src/lib/fuchsia-cxx/result.h");
/// type Result = fuchsia_cxx::Result;
/// }
///
/// struct FooResult {
/// result: Result,
/// foo: Box<Foo>,
/// }
///
/// extern "Rust" {
/// type Foo;
/// fn new_foo() -> FooResult;
/// fn use_foo(self: &Foo) -> Result;
/// }
/// }
///
/// TODO(fxbug.dev/71142): Once CXX has support for Results with a generic error type and
/// non-throw/panic behavior, this type can become just the error part of the result.
pub struct Result {
// On success, equal to ZX_OK (0). On error, a non-zero ZX_ERR_* Zircon status value.
status: i32,
// On success, this is empty. On error, the stringified (with Display) Rust error.
message: String,
}
}
impl ffi::Result {
pub fn ok() -> ffi::Result {
ffi::Result { status: zx::Status::OK.into_raw(), message: String::new() }
}
// This can't be a From impl because then it conflicts with the std::result::Result impl below,
// even though std::result::Result could never actually impl Into<zx::Status>.
pub fn from_error<T>(error: T) -> ffi::Result
where
T: Into<zx::Status> + std::fmt::Display,
{
let message = error.to_string();
ffi::Result { status: error.into().into_raw(), message }
}
}
// This allows for easy conversion from the std Result type to ffi::Result as long as your error
// type implements Into<zx::Status>.
impl<T> From<std::result::Result<(), T>> for ffi::Result
where
T: Into<zx::Status> + std::fmt::Display,
{
fn from(result: std::result::Result<(), T>) -> Self {
match result {
Ok(()) => ffi::Result::ok(),
Err(err) => ffi::Result::from_error(err),
}
}
}