<commit_before>//! Actix web is a small, fast, pragmatic, open source rust web framework.
//!
//! ```rust
//! use actix_web::*;
//! # use std::thread;
//!
//! fn index(req: HttpRequest) -> String {
//!     format!("Hello {}!", &req.match_info()["name"])
//! }
//!
//! fn main() {
//! # thread::spawn(|| {
//!     HttpServer::new(
//!         || Application::new()
//!             .resource("/{name}", |r| r.f(index)))
//!         .bind("127.0.0.1:8080").unwrap()
//!         .run();
//! # });
//! }
//! ```
//!
//! ## Documentation
//!
//! * [User Guide](http://actix.github.io/actix-web/guide/)
//! * Cargo package: [actix-web](https://crates.io/crates/actix-web)
//! * Minimum supported Rust version: 1.20 or later
//!
//! ## Features
//!
//! * Supported *HTTP/1.x* and *HTTP/2.0* protocols
//! * Streaming and pipelining
//! * Keep-alive and slow requests handling
//! * `WebSockets`
//! * Transparent content compression/decompression (br, gzip, deflate)
//! * Configurable request routing
//! * Multipart streams
//! * Middlewares (`Logger`, `Session`, `DefaultHeaders`)
//! * Graceful server shutdown
//! * Built on top of [Actix](https://github.com/actix/actix).

#![cfg_attr(actix_nightly, feature(
    specialization, // for impl ErrorResponse for std::error::Error
))]

#[macro_use]
extern crate log;
extern crate time;
extern crate bytes;
extern crate sha1;
extern crate regex;
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate failure;
#[macro_use]
extern crate futures;
extern crate tokio_io;
extern crate tokio_core;
extern crate mio;
extern crate net2;
extern crate cookie;
extern crate http;
extern crate httparse;
extern crate http_range;
extern crate mime;
extern crate mime_guess;
extern crate url;
extern crate libc;
extern crate serde;
extern crate serde_json;
extern crate flate2;
extern crate brotli2;
extern crate percent_encoding;
extern crate smallvec;
extern crate num_cpus;
extern crate h2 as http2;
#[macro_use] extern crate actix;

#[cfg(test)]
#[macro_use] extern crate serde_derive;

#[cfg(feature="tls")]
extern crate native_tls;
#[cfg(feature="tls")]
extern crate tokio_tls;

#[cfg(feature="openssl")]
extern crate openssl;
#[cfg(feature="openssl")]
extern crate tokio_openssl;

mod application;
mod body;
mod context;
mod helpers;
mod httprequest;
mod httpresponse;
mod info;
mod json;
mod route;
mod router;
mod param;
mod resource;
mod handler;
mod pipeline;

pub mod fs;
pub mod ws;
pub mod error;
pub mod httpcodes;
pub mod multipart;
pub mod middleware;
pub mod pred;
pub mod test;
pub mod payload;
pub mod server;
pub use error::{Error, Result, ResponseError};
pub use body::{Body, Binary};
pub use json::Json;
pub use application::Application;
pub use httprequest::HttpRequest;
pub use httpresponse::HttpResponse;
pub use handler::{Reply, Responder, NormalizePath, AsyncResponder};
pub use route::Route;
pub use resource::Resource;
pub use context::HttpContext;
pub use server::HttpServer;

// re-exports
pub use http::{Method, StatusCode, Version};

#[doc(hidden)]
#[cfg(feature="tls")]
pub use native_tls::Pkcs12;

#[doc(hidden)]
#[cfg(feature="openssl")]
pub use openssl::pkcs12::Pkcs12;

pub mod headers {
//! Headers implementation

    pub use httpresponse::ConnectionType;

    pub use cookie::{Cookie, CookieBuilder};
    pub use http_range::HttpRange;

    /// Represents supported types of content encodings
    #[derive(Copy, Clone, PartialEq, Debug)]
    pub enum ContentEncoding {
        /// Automatically select encoding based on encoding negotiation
        Auto,
        /// A format using the Brotli algorithm
        Br,
        /// A format using the zlib structure with deflate algorithm
        Deflate,
        /// Gzip algorithm
        Gzip,
        /// Indicates the identity function (i.e. no compression, nor modification)
        Identity,
    }
}

pub mod dev {
//! The `actix-web` prelude for library developers
//!
//! The purpose of this module is to alleviate imports of many common actix traits
//! by adding a glob import to the top of actix heavy modules:
//!
//! ```
//! # #![allow(unused_imports)]
//! use actix_web::dev::*;
//! ```

    pub use body::BodyStream;
    pub use info::ConnectionInfo;
    pub use handler::Handler;
    pub use json::JsonBody;
    pub use router::{Router, Pattern};
    pub use param::{FromParam, Params};
    pub use httprequest::{UrlEncoded, RequestBody};
    pub use httpresponse::HttpResponseBuilder;
}
<commit_msg>add link to github<commit_after>//! Actix web is a small, fast, pragmatic, open source rust web framework.
//!
//! ```rust
//! use actix_web::*;
//! # use std::thread;
//!
//! fn index(req: HttpRequest) -> String {
//!     format!("Hello {}!", &req.match_info()["name"])
//! }
//!
//! fn main() {
//! # thread::spawn(|| {
//!     HttpServer::new(
//!         || Application::new()
//!             .resource("/{name}", |r| r.f(index)))
//!         .bind("127.0.0.1:8080").unwrap()
//!         .run();
//! # });
//! }
//! ```
//!
//! ## Documentation
//!
//! * [User Guide](http://actix.github.io/actix-web/guide/)
//! * Cargo package: [actix-web](https://crates.io/crates/actix-web)
//! * [GitHub repository](https://github.com/actix/actix-web)
//! * Supported Rust version: 1.20 or later
//!
//! ## Features
//!
//! * Supported *HTTP/1.x* and *HTTP/2.0* protocols
//! * Streaming and pipelining
//! * Keep-alive and slow requests handling
//! * `WebSockets`
//! * Transparent content compression/decompression (br, gzip, deflate)
//! * Configurable request routing
//! * Multipart streams
//! * Middlewares (`Logger`, `Session`, `DefaultHeaders`)
//! * Graceful server shutdown
//! * Built on top of [Actix](https://github.com/actix/actix).

#![cfg_attr(actix_nightly, feature(
    specialization, // for impl ErrorResponse for std::error::Error
))]

#[macro_use]
extern crate log;
extern crate time;
extern crate bytes;
extern crate sha1;
extern crate regex;
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate failure;
#[macro_use]
extern crate futures;
extern crate tokio_io;
extern crate tokio_core;
extern crate mio;
extern crate net2;
extern crate cookie;
extern crate http;
extern crate httparse;
extern crate http_range;
extern crate mime;
extern crate mime_guess;
extern crate url;
extern crate libc;
extern crate serde;
extern crate serde_json;
extern crate flate2;
extern crate brotli2;
extern crate percent_encoding;
extern crate smallvec;
extern crate num_cpus;
extern crate h2 as http2;
#[macro_use] extern crate actix;

#[cfg(test)]
#[macro_use] extern crate serde_derive;

#[cfg(feature="tls")]
extern crate native_tls;
#[cfg(feature="tls")]
extern crate tokio_tls;

#[cfg(feature="openssl")]
extern crate openssl;
#[cfg(feature="openssl")]
extern crate tokio_openssl;

mod application;
mod body;
mod context;
mod helpers;
mod httprequest;
mod httpresponse;
mod info;
mod json;
mod route;
mod router;
mod param;
mod resource;
mod handler;
mod pipeline;

pub mod fs;
pub mod ws;
pub mod error;
pub mod httpcodes;
pub mod multipart;
pub mod middleware;
pub mod pred;
pub mod test;
pub mod payload;
pub mod server;
pub use error::{Error, Result, ResponseError};
pub use body::{Body, Binary};
pub use json::Json;
pub use application::Application;
pub use httprequest::HttpRequest;
pub use httpresponse::HttpResponse;
pub use handler::{Reply, Responder, NormalizePath, AsyncResponder};
pub use route::Route;
pub use resource::Resource;
pub use context::HttpContext;
pub use server::HttpServer;

// re-exports
pub use http::{Method, StatusCode, Version};

#[doc(hidden)]
#[cfg(feature="tls")]
pub use native_tls::Pkcs12;

#[doc(hidden)]
#[cfg(feature="openssl")]
pub use openssl::pkcs12::Pkcs12;

pub mod headers {
//! Headers implementation

    pub use httpresponse::ConnectionType;

    pub use cookie::{Cookie, CookieBuilder};
    pub use http_range::HttpRange;

    /// Represents supported types of content encodings
    #[derive(Copy, Clone, PartialEq, Debug)]
    pub enum ContentEncoding {
        /// Automatically select encoding based on encoding negotiation
        Auto,
        /// A format using the Brotli algorithm
        Br,
        /// A format using the zlib structure with deflate algorithm
        Deflate,
        /// Gzip algorithm
        Gzip,
        /// Indicates the identity function (i.e. no compression, nor modification)
        Identity,
    }
}

pub mod dev {
//! The `actix-web` prelude for library developers
//!
//! The purpose of this module is to alleviate imports of many common actix traits
//! by adding a glob import to the top of actix heavy modules:
//!
//! ```
//! # #![allow(unused_imports)]
//! use actix_web::dev::*;
//! ```

    pub use body::BodyStream;
    pub use info::ConnectionInfo;
    pub use handler::Handler;
    pub use json::JsonBody;
    pub use router::{Router, Pattern};
    pub use param::{FromParam, Params};
    pub use httprequest::{UrlEncoded, RequestBody};
    pub use httpresponse::HttpResponseBuilder;
}
<|endoftext|>


<commit_before>#![feature(rustc_private)]
#![feature(map_first_last)]
#![feature(map_try_insert)]
#![feature(never_type)]
#![feature(try_blocks)]
#![feature(let_else)]
#![feature(io_error_more)]
#![warn(rust_2018_idioms)]
#![allow(
    clippy::collapsible_else_if,
    clippy::collapsible_if,
    clippy::comparison_chain,
    clippy::enum_variant_names,
    clippy::field_reassign_with_default,
    clippy::manual_map,
    clippy::new_without_default,
    clippy::single_match,
    clippy::useless_format,
    clippy::derive_partial_eq_without_eq
)]

extern crate rustc_apfloat;
extern crate rustc_ast;
#[macro_use]
extern crate rustc_middle;
extern crate rustc_const_eval;
extern crate rustc_data_structures;
extern crate rustc_hir;
extern crate rustc_index;
extern crate rustc_session;
extern crate rustc_span;
extern crate rustc_target;

mod concurrency;
mod diagnostics;
mod eval;
mod helpers;
mod intptrcast;
mod machine;
mod mono_hash_map;
mod operator;
mod range_map;
mod shims;
mod stacked_borrows;
mod sync;
mod thread;
mod vector_clock;

// Establish a "crate-wide prelude": we often import `crate::*`.

// Make all those symbols available in the same place as our own.
pub use rustc_const_eval::interpret::*;
// Resolve ambiguity.
pub use rustc_const_eval::interpret::{self, AllocMap, PlaceTy};

pub use crate::shims::dlsym::{Dlsym, EvalContextExt as _};
pub use crate::shims::env::{EnvVars, EvalContextExt as _};
pub use crate::shims::foreign_items::EvalContextExt as _;
pub use crate::shims::intrinsics::EvalContextExt as _;
pub use crate::shims::os_str::EvalContextExt as _;
pub use crate::shims::panic::{CatchUnwindData, EvalContextExt as _};
pub use crate::shims::time::EvalContextExt as _;
pub use crate::shims::tls::{EvalContextExt as _, TlsData};
pub use crate::shims::EvalContextExt as _;

pub use crate::concurrency::data_race::{
    AtomicFenceOp, AtomicReadOp, AtomicRwOp, AtomicWriteOp,
    EvalContextExt as DataRaceEvalContextExt,
};
pub use crate::diagnostics::{
    register_diagnostic, report_error, EvalContextExt as DiagnosticsEvalContextExt,
    NonHaltingDiagnostic, TerminationInfo,
};
pub use crate::eval::{
    create_ecx, eval_entry, AlignmentCheck, BacktraceStyle, IsolatedOp, MiriConfig, RejectOpWith,
};
pub use crate::helpers::{CurrentSpan, EvalContextExt as HelpersEvalContextExt};
pub use crate::intptrcast::ProvenanceMode;
pub use crate::machine::{
    AllocExtra, ConcreteTag, Evaluator, FrameData, MiriEvalContext, MiriEvalContextExt,
    MiriMemoryKind, Tag, NUM_CPUS, PAGE_SIZE, STACK_ADDR, STACK_SIZE,
};
pub use crate::mono_hash_map::MonoHashMap;
pub use crate::operator::EvalContextExt as OperatorEvalContextExt;
pub use crate::range_map::RangeMap;
pub use crate::stacked_borrows::{
    CallId, EvalContextExt as StackedBorEvalContextExt, Item, Permission, PtrId, SbTag, Stack,
    Stacks,
};
pub use crate::sync::{CondvarId, EvalContextExt as SyncEvalContextExt, MutexId, RwLockId};
pub use crate::thread::{
    EvalContextExt as ThreadsEvalContextExt, SchedulingAction, ThreadId, ThreadManager, ThreadState,
};
pub use crate::vector_clock::{VClock, VTimestamp, VectorIdx};

/// Insert rustc arguments at the beginning of the argument list that Miri wants to be
/// set per default, for maximal validation power.
pub const MIRI_DEFAULT_ARGS: &[&str] = &[
    "-Zalways-encode-mir",
    "-Zmir-emit-retag",
    "-Zmir-opt-level=0",
    "--cfg=miri",
    "-Cdebug-assertions=on",
];
<commit_msg>silence another clippy lint<commit_after>#![feature(rustc_private)]
#![feature(map_first_last)]
#![feature(map_try_insert)]
#![feature(never_type)]
#![feature(try_blocks)]
#![feature(let_else)]
#![feature(io_error_more)]
#![warn(rust_2018_idioms)]
#![allow(
    clippy::collapsible_else_if,
    clippy::collapsible_if,
    clippy::comparison_chain,
    clippy::enum_variant_names,
    clippy::field_reassign_with_default,
    clippy::manual_map,
    clippy::new_without_default,
    clippy::single_match,
    clippy::useless_format,
    clippy::derive_partial_eq_without_eq,
    clippy::too_many_arguments
)]

extern crate rustc_apfloat;
extern crate rustc_ast;
#[macro_use]
extern crate rustc_middle;
extern crate rustc_const_eval;
extern crate rustc_data_structures;
extern crate rustc_hir;
extern crate rustc_index;
extern crate rustc_session;
extern crate rustc_span;
extern crate rustc_target;

mod concurrency;
mod diagnostics;
mod eval;
mod helpers;
mod intptrcast;
mod machine;
mod mono_hash_map;
mod operator;
mod range_map;
mod shims;
mod stacked_borrows;
mod sync;
mod thread;
mod vector_clock;

// Establish a "crate-wide prelude": we often import `crate::*`.

// Make all those symbols available in the same place as our own.
pub use rustc_const_eval::interpret::*;
// Resolve ambiguity.
pub use rustc_const_eval::interpret::{self, AllocMap, PlaceTy};

pub use crate::shims::dlsym::{Dlsym, EvalContextExt as _};
pub use crate::shims::env::{EnvVars, EvalContextExt as _};
pub use crate::shims::foreign_items::EvalContextExt as _;
pub use crate::shims::intrinsics::EvalContextExt as _;
pub use crate::shims::os_str::EvalContextExt as _;
pub use crate::shims::panic::{CatchUnwindData, EvalContextExt as _};
pub use crate::shims::time::EvalContextExt as _;
pub use crate::shims::tls::{EvalContextExt as _, TlsData};
pub use crate::shims::EvalContextExt as _;

pub use crate::concurrency::data_race::{
    AtomicFenceOp, AtomicReadOp, AtomicRwOp, AtomicWriteOp,
    EvalContextExt as DataRaceEvalContextExt,
};
pub use crate::diagnostics::{
    register_diagnostic, report_error, EvalContextExt as DiagnosticsEvalContextExt,
    NonHaltingDiagnostic, TerminationInfo,
};
pub use crate::eval::{
    create_ecx, eval_entry, AlignmentCheck, BacktraceStyle, IsolatedOp, MiriConfig, RejectOpWith,
};
pub use crate::helpers::{CurrentSpan, EvalContextExt as HelpersEvalContextExt};
pub use crate::intptrcast::ProvenanceMode;
pub use crate::machine::{
    AllocExtra, ConcreteTag, Evaluator, FrameData, MiriEvalContext, MiriEvalContextExt,
    MiriMemoryKind, Tag, NUM_CPUS, PAGE_SIZE, STACK_ADDR, STACK_SIZE,
};
pub use crate::mono_hash_map::MonoHashMap;
pub use crate::operator::EvalContextExt as OperatorEvalContextExt;
pub use crate::range_map::RangeMap;
pub use crate::stacked_borrows::{
    CallId, EvalContextExt as StackedBorEvalContextExt, Item, Permission, PtrId, SbTag, Stack,
    Stacks,
};
pub use crate::sync::{CondvarId, EvalContextExt as SyncEvalContextExt, MutexId, RwLockId};
pub use crate::thread::{
    EvalContextExt as ThreadsEvalContextExt, SchedulingAction, ThreadId, ThreadManager, ThreadState,
};
pub use crate::vector_clock::{VClock, VTimestamp, VectorIdx};

/// Insert rustc arguments at the beginning of the argument list that Miri wants to be
/// set per default, for maximal validation power.
pub const MIRI_DEFAULT_ARGS: &[&str] = &[
    "-Zalways-encode-mir",
    "-Zmir-emit-retag",
    "-Zmir-opt-level=0",
    "--cfg=miri",
    "-Cdebug-assertions=on",
];
<|endoftext|>


<commit_before>#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;

#[macro_use]
mod macros;

pub mod callbacks;
pub mod crypto;
pub mod did;
pub mod ledger;
pub mod payments;
pub mod pool;
pub mod wallet;
pub mod utils;

mod ffi;

use std::sync::mpsc;

pub type IndyHandle = i32;

#[derive(Debug, PartialEq, Copy, Clone)]
#[repr(i32)]
#[allow(dead_code)]
pub enum ErrorCode
{
    Success = 0,

    // Common errors

    // Caller passed invalid value as param 1 (null, invalid json and etc..)
    CommonInvalidParam1 = 100,

    // Caller passed invalid value as param 2 (null, invalid json and etc..)
    CommonInvalidParam2 = 101,

    // Caller passed invalid value as param 3 (null, invalid json and etc..)
    CommonInvalidParam3 = 102,

    // Caller passed invalid value as param 4 (null, invalid json and etc..)
    CommonInvalidParam4 = 103,

    // Caller passed invalid value as param 5 (null, invalid json and etc..)
    CommonInvalidParam5 = 104,

    // Caller passed invalid value as param 6 (null, invalid json and etc..)
    CommonInvalidParam6 = 105,

    // Caller passed invalid value as param 7 (null, invalid json and etc..)
    CommonInvalidParam7 = 106,

    // Caller passed invalid value as param 8 (null, invalid json and etc..)
    CommonInvalidParam8 = 107,

    // Caller passed invalid value as param 9 (null, invalid json and etc..)
    CommonInvalidParam9 = 108,

    // Caller passed invalid value as param 10 (null, invalid json and etc..)
    CommonInvalidParam10 = 109,

    // Caller passed invalid value as param 11 (null, invalid json and etc..)
    CommonInvalidParam11 = 110,

    // Caller passed invalid value as param 11 (null, invalid json and etc..)
    CommonInvalidParam12 = 111,

    // Invalid library state was detected in runtime. It signals library bug
    CommonInvalidState = 112,

    // Object (json, config, key, credential and etc...) passed by library caller has invalid structure
    CommonInvalidStructure = 113,

    // IO Error
    CommonIOError = 114,

    // Wallet errors
    // Caller passed invalid wallet handle
    WalletInvalidHandle = 200,

    // Unknown type of wallet was passed on create_wallet
    WalletUnknownTypeError = 201,

    // Attempt to register already existing wallet type
    WalletTypeAlreadyRegisteredError = 202,

    // Attempt to create wallet with name used for another exists wallet
    WalletAlreadyExistsError = 203,

    // Requested entity id isn't present in wallet
    WalletNotFoundError = 204,

    // Trying to use wallet with pool that has different name
    WalletIncompatiblePoolError = 205,

    // Trying to open wallet that was opened already
    WalletAlreadyOpenedError = 206,

    // Attempt to open encrypted wallet with invalid credentials
    WalletAccessFailed = 207,

    // Ledger errors
    // Trying to open pool ledger that wasn't created before
    PoolLedgerNotCreatedError = 300,

    // Caller passed invalid pool ledger handle
    PoolLedgerInvalidPoolHandle = 301,

    // Pool ledger terminated
    PoolLedgerTerminated = 302,

    // No concensus during ledger operation
    LedgerNoConsensusError = 303,

    // Attempt to parse invalid transaction response
    LedgerInvalidTransaction = 304,

    // Attempt to send transaction without the necessary privileges
    LedgerSecurityError = 305,

    // Attempt to create pool ledger config with name used for another existing pool
    PoolLedgerConfigAlreadyExistsError = 306,

    // Timeout for action
    PoolLedgerTimeout = 307,

    // Revocation registry is full and creation of new registry is necessary
    AnoncredsRevocationRegistryFullError = 400,

    AnoncredsInvalidUserRevocIndex = 401,

    AnoncredsAccumulatorIsFull = 402,

    AnoncredsNotIssuedError = 403,

    // Attempt to generate master secret with duplicated name
    AnoncredsMasterSecretDuplicateNameError = 404,

    AnoncredsProofRejected = 405,

    AnoncredsCredentialRevoked = 406,

    // Attempt to create credential definition with duplicated did schema pair
    AnoncredsCredDefAlreadyExistsError = 407,

    // Signus errors
    // Unknown format of DID entity keys
    UnknownCryptoTypeError = 500,

    // Attempt to create duplicate did
    DidAlreadyExistsError = 600,

    // Unknown payment method was given
    UnknownPaymentMethod = 700,

    //No method were scraped from inputs/outputs or more than one were scraped
    IncompatiblePaymentError = 701
}

impl ErrorCode {
    #[allow(non_snake_case)]
    #[allow(dead_code)]
    #[allow(unused)]
    pub fn description(&self) -> &'static str {
        match self {
            CommonInvalidParam1 => "Caller passed invalid value as param 1",
            CommonInvalidParam2 => "Caller passed invalid value as param 2",
            CommonInvalidParam3 => "Caller passed invalid value as param 3",
            CommonInvalidParam4 => "Caller passed invalid value as param 4",
            CommonInvalidParam5 => "Caller passed invalid value as param 5",
            CommonInvalidParam6 => "Caller passed invalid value as param 6",
            CommonInvalidParam7 => "Caller passed invalid value as param 7",
            CommonInvalidParam8 => "Caller passed invalid value as param 8",
            CommonInvalidParam9 => "Caller passed invalid value as param 9",
            CommonInvalidParam10 => "Caller passed invalid value as param 10",
            CommonInvalidParam11 => "Caller passed invalid value as param 11",
            CommonInvalidParam12 => "Caller passed invalid value as param 12",
            CommonInvalidState => "Invalid library state was detected in runtime. It signals library bug",
            CommonInvalidStructure => "Object (json, config, key, credential and etc...) passed by library caller has invalid structure",
            CommonIOError => "IO Error",
            WalletInvalidHandle => "Caller passed invalid wallet handle",
            WalletUnknownTypeError => "Caller passed invalid wallet handle",
            WalletTypeAlreadyRegisteredError => "Attempt to register already existing wallet type",
            WalletAlreadyExistsError => "Attempt to create wallet with name used for another exists wallet",
            WalletNotFoundError => "Requested entity id isn't present in wallet",
            WalletIncompatiblePoolError => "Trying to use wallet with pool that has different name",
            WalletAccessFailed => "Trying to open wallet encrypted wallet with invalid credentials",
            WalletAlreadyOpenedError => "Trying to open wallet that was opened already",
            PoolLedgerNotCreatedError => "Trying to open pool ledger that wasn't created before",
            PoolLedgerInvalidPoolHandle => "Caller passed invalid pool ledger handle",
            PoolLedgerTerminated => "Pool ledger terminated",
            LedgerNoConsensusError => "No concensus during ledger operation",
            LedgerInvalidTransaction => "Attempt to send unknown or incomplete transaction message",
            LedgerSecurityError => "Attempt to send transaction without the necessary privileges",
            PoolLedgerConfigAlreadyExistsError => "Attempt to create pool ledger config with name used for another existing pool",
            AnoncredsRevocationRegistryFullError => "Revocation registry is full and creation of new registry is necessary",
            AnoncredsInvalidUserRevocIndex => "Invalid user revocation index",
            AnoncredsAccumulatorIsFull => "Revocation accumulator is full",
            AnoncredsNotIssuedError => "Not issued",
            AnoncredsMasterSecretDuplicateNameError => "Attempt to generate master secret with duplicated name",
            AnoncredsProofRejected => "Proof rejected",
            AnoncredsCredentialRevoked => "Credential revoked",
            AnoncredsCredDefAlreadyExistsError => "Credential definition already exists",
            UnknownCryptoTypeError => "Unknown format of DID entity keys",
            DidAlreadyExistsError => "Did already exists",
            UnknownPaymentMethod => "Unknown payment method was given",
            IncompatiblePaymentError => "Multiple different payment methods were specified",
        }
    }

    pub fn is_ok(&self) -> bool {
        *self == ErrorCode::Success
    }

    pub fn is_err(&self) -> bool {
        *self != ErrorCode::Success
    }

    pub fn try_err(&self) -> Result<(), ErrorCode> {
        if self.is_err() {
            return Err(*self)
        }
        Ok(())
    }
}

impl From<mpsc::RecvTimeoutError> for ErrorCode {
    fn from(err: mpsc::RecvTimeoutError) -> Self {
        match err {
            mpsc::RecvTimeoutError::Timeout => {
                warn!("Timed out waiting for libindy to call back");
                ErrorCode::CommonIOError
            },
            mpsc::RecvTimeoutError::Disconnected => {
                warn!("Channel to libindy was disconnected unexpectedly");
                ErrorCode::CommonIOError
            }
        }
    }
}

impl From<mpsc::RecvError> for ErrorCode {
    fn from(_: mpsc::RecvError) -> Self {
        warn!("Channel returned an error.");
        ErrorCode::CommonIOError
    }
}
<commit_msg>Better error message<commit_after>#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;

#[macro_use]
mod macros;

pub mod callbacks;
pub mod crypto;
pub mod did;
pub mod ledger;
pub mod payments;
pub mod pool;
pub mod wallet;
pub mod utils;

mod ffi;

use std::sync::mpsc;

pub type IndyHandle = i32;

#[derive(Debug, PartialEq, Copy, Clone)]
#[repr(i32)]
#[allow(dead_code)]
pub enum ErrorCode
{
    Success = 0,

    // Common errors

    // Caller passed invalid value as param 1 (null, invalid json and etc..)
    CommonInvalidParam1 = 100,

    // Caller passed invalid value as param 2 (null, invalid json and etc..)
    CommonInvalidParam2 = 101,

    // Caller passed invalid value as param 3 (null, invalid json and etc..)
    CommonInvalidParam3 = 102,

    // Caller passed invalid value as param 4 (null, invalid json and etc..)
    CommonInvalidParam4 = 103,

    // Caller passed invalid value as param 5 (null, invalid json and etc..)
    CommonInvalidParam5 = 104,

    // Caller passed invalid value as param 6 (null, invalid json and etc..)
    CommonInvalidParam6 = 105,

    // Caller passed invalid value as param 7 (null, invalid json and etc..)
    CommonInvalidParam7 = 106,

    // Caller passed invalid value as param 8 (null, invalid json and etc..)
    CommonInvalidParam8 = 107,

    // Caller passed invalid value as param 9 (null, invalid json and etc..)
    CommonInvalidParam9 = 108,

    // Caller passed invalid value as param 10 (null, invalid json and etc..)
    CommonInvalidParam10 = 109,

    // Caller passed invalid value as param 11 (null, invalid json and etc..)
    CommonInvalidParam11 = 110,

    // Caller passed invalid value as param 11 (null, invalid json and etc..)
    CommonInvalidParam12 = 111,

    // Invalid library state was detected in runtime. It signals library bug
    CommonInvalidState = 112,

    // Object (json, config, key, credential and etc...) passed by library caller has invalid structure
    CommonInvalidStructure = 113,

    // IO Error
    CommonIOError = 114,

    // Wallet errors
    // Caller passed invalid wallet handle
    WalletInvalidHandle = 200,

    // Unknown type of wallet was passed on create_wallet
    WalletUnknownTypeError = 201,

    // Attempt to register already existing wallet type
    WalletTypeAlreadyRegisteredError = 202,

    // Attempt to create wallet with name used for another exists wallet
    WalletAlreadyExistsError = 203,

    // Requested entity id isn't present in wallet
    WalletNotFoundError = 204,

    // Trying to use wallet with pool that has different name
    WalletIncompatiblePoolError = 205,

    // Trying to open wallet that was opened already
    WalletAlreadyOpenedError = 206,

    // Attempt to open encrypted wallet with invalid credentials
    WalletAccessFailed = 207,

    // Ledger errors
    // Trying to open pool ledger that wasn't created before
    PoolLedgerNotCreatedError = 300,

    // Caller passed invalid pool ledger handle
    PoolLedgerInvalidPoolHandle = 301,

    // Pool ledger terminated
    PoolLedgerTerminated = 302,

    // No concensus during ledger operation
    LedgerNoConsensusError = 303,

    // Attempt to parse invalid transaction response
    LedgerInvalidTransaction = 304,

    // Attempt to send transaction without the necessary privileges
    LedgerSecurityError = 305,

    // Attempt to create pool ledger config with name used for another existing pool
    PoolLedgerConfigAlreadyExistsError = 306,

    // Timeout for action
    PoolLedgerTimeout = 307,

    // Revocation registry is full and creation of new registry is necessary
    AnoncredsRevocationRegistryFullError = 400,

    AnoncredsInvalidUserRevocIndex = 401,

    AnoncredsAccumulatorIsFull = 402,

    AnoncredsNotIssuedError = 403,

    // Attempt to generate master secret with duplicated name
    AnoncredsMasterSecretDuplicateNameError = 404,

    AnoncredsProofRejected = 405,

    AnoncredsCredentialRevoked = 406,

    // Attempt to create credential definition with duplicated did schema pair
    AnoncredsCredDefAlreadyExistsError = 407,

    // Signus errors
    // Unknown format of DID entity keys
    UnknownCryptoTypeError = 500,

    // Attempt to create duplicate did
    DidAlreadyExistsError = 600,

    // Unknown payment method was given
    UnknownPaymentMethod = 700,

    //No method were scraped from inputs/outputs or more than one were scraped
    IncompatiblePaymentError = 701
}

impl ErrorCode {
    #[allow(non_snake_case)]
    #[allow(dead_code)]
    #[allow(unused)]
    pub fn description(&self) -> &'static str {
        match self {
            CommonInvalidParam1 => "Caller passed invalid value as param 1",
            CommonInvalidParam2 => "Caller passed invalid value as param 2",
            CommonInvalidParam3 => "Caller passed invalid value as param 3",
            CommonInvalidParam4 => "Caller passed invalid value as param 4",
            CommonInvalidParam5 => "Caller passed invalid value as param 5",
            CommonInvalidParam6 => "Caller passed invalid value as param 6",
            CommonInvalidParam7 => "Caller passed invalid value as param 7",
            CommonInvalidParam8 => "Caller passed invalid value as param 8",
            CommonInvalidParam9 => "Caller passed invalid value as param 9",
            CommonInvalidParam10 => "Caller passed invalid value as param 10",
            CommonInvalidParam11 => "Caller passed invalid value as param 11",
            CommonInvalidParam12 => "Caller passed invalid value as param 12",
            CommonInvalidState => "Invalid library state was detected in runtime. It signals library bug",
            CommonInvalidStructure => "Object (json, config, key, credential and etc...) passed by library caller has invalid structure",
            CommonIOError => "IO Error",
            WalletInvalidHandle => "Caller passed invalid wallet handle",
            WalletUnknownTypeError => "Caller passed invalid wallet handle",
            WalletTypeAlreadyRegisteredError => "Attempt to register already existing wallet type",
            WalletAlreadyExistsError => "Attempt to create wallet with name used for another exists wallet",
            WalletNotFoundError => "Requested entity id isn't present in wallet",
            WalletIncompatiblePoolError => "Trying to use wallet with pool that has different name",
            WalletAccessFailed => "Trying to open wallet encrypted wallet with invalid credentials",
            WalletAlreadyOpenedError => "Trying to open wallet that was opened already",
            PoolLedgerNotCreatedError => "Trying to open pool ledger that wasn't created before",
            PoolLedgerInvalidPoolHandle => "Caller passed invalid pool ledger handle",
            PoolLedgerTerminated => "Pool ledger terminated",
            LedgerNoConsensusError => "No concensus during ledger operation",
            LedgerInvalidTransaction => "Attempt to send unknown or incomplete transaction message",
            LedgerSecurityError => "Attempt to send transaction without the necessary privileges",
            PoolLedgerConfigAlreadyExistsError => "Attempt to create pool ledger config with name used for another existing pool",
            AnoncredsRevocationRegistryFullError => "Revocation registry is full and creation of new registry is necessary",
            AnoncredsInvalidUserRevocIndex => "Invalid user revocation index",
            AnoncredsAccumulatorIsFull => "Revocation accumulator is full",
            AnoncredsNotIssuedError => "Not issued",
            AnoncredsMasterSecretDuplicateNameError => "Attempt to generate master secret with duplicated name",
            AnoncredsProofRejected => "Proof rejected",
            AnoncredsCredentialRevoked => "Credential revoked",
            AnoncredsCredDefAlreadyExistsError => "Credential definition already exists",
            UnknownCryptoTypeError => "Unknown format of DID entity keys",
            DidAlreadyExistsError => "Did already exists",
            UnknownPaymentMethod => "Unknown payment method was given",
            IncompatiblePaymentError => "Multiple different payment methods were specified",
        }
    }

    pub fn is_ok(&self) -> bool {
        *self == ErrorCode::Success
    }

    pub fn is_err(&self) -> bool {
        *self != ErrorCode::Success
    }

    pub fn try_err(&self) -> Result<(), ErrorCode> {
        if self.is_err() {
            return Err(*self)
        }
        Ok(())
    }
}

impl From<mpsc::RecvTimeoutError> for ErrorCode {
    fn from(err: mpsc::RecvTimeoutError) -> Self {
        match err {
            mpsc::RecvTimeoutError::Timeout => {
                warn!("Timed out waiting for libindy to call back");
                ErrorCode::CommonIOError
            },
            mpsc::RecvTimeoutError::Disconnected => {
                warn!("Channel to libindy was disconnected unexpectedly");
                ErrorCode::CommonIOError
            }
        }
    }
}

impl From<mpsc::RecvError> for ErrorCode {
    fn from(e: mpsc::RecvError) -> Self {
        warn!("Channel returned an error - {:?}", e);
        ErrorCode::CommonIOError
    }
}
<|endoftext|>


<commit_before>#![deny(missing_docs)]
#![feature(unsafe_destructor)]
#![unstable]

//! A library for setting current values for stack scope,
//! such as application structure.

use std::cell::RefCell;
use std::intrinsics::TypeId;
use std::collections::HashMap;
use std::collections::hash_map::Entry::{ Occupied, Vacant };
use std::ops::{ Deref, DerefMut };

// Stores the current pointers for concrete types.
thread_local!(static KEY_CURRENT: RefCell<HashMap<TypeId, uint>>
    = RefCell::new(HashMap::new()));

/// Puts back the previous current pointer.
#[unstable]
pub struct CurrentGuard<'a, T: 'a> {
    _val: &'a mut T,
    old_ptr: Option<uint>
}

#[unstable]
impl<'a, T: 'static> CurrentGuard<'a, T> {
    /// Creates a new current guard.
    #[unstable]
    pub fn new(val: &mut T) -> CurrentGuard<T> {
        let id = TypeId::of::<T>();
        let ptr = val as *mut T as uint;
        let old_ptr = KEY_CURRENT.with(|current| {
            match current.borrow_mut().entry(&id) {
                Occupied(mut entry) => Some(entry.insert(ptr)),
                Vacant(entry) => {
                    entry.insert(ptr);
                    None
                }
            }
        });
        CurrentGuard { old_ptr: old_ptr, _val: val }
    }
}

#[unsafe_destructor]
impl<'a, T: 'static> Drop for CurrentGuard<'a, T> {
    fn drop(&mut self) {
        let id = TypeId::of::<T>();
        match self.old_ptr {
            None => {
                KEY_CURRENT.with(|current| {
                    current.borrow_mut().remove(&id);
                });
                return;
            }
            Some(old_ptr) => {
                KEY_CURRENT.with(|current| {
                    match current.borrow_mut().entry(&id) {
                        Occupied(mut entry) => { entry.insert(old_ptr); }
                        Vacant(entry) => { entry.insert(old_ptr); }
                    };
                });
            }
        };
    }
}

/// The current value of a type.
#[unstable]
pub struct Current<T>(());

#[unstable]
impl<T: 'static> Current<T> {
    /// Creates a new current object
    #[unstable]
    pub unsafe fn new() -> Current<T> { Current(()) }

    /// Gets mutable reference to current object.
    /// Requires mutable reference to prevent access to globals in safe code,
    /// and to prevent mutable borrows of same value in scope.
    /// Is unsafe because returned reference inherits lifetime from argument.
    #[unstable]
    pub unsafe fn current(&mut self) -> Option<&mut T> {
        use std::mem::transmute;
        let id = TypeId::of::<T>();
        let ptr: Option<uint> = KEY_CURRENT.with(|current| {
                current.borrow().get(&id).map(|id| *id)
            });
        let ptr = match ptr { None => { return None; } Some(x) => x };
        Some(transmute(ptr as *mut T))
    }

    /// Unwraps mutable reference to current object,
    /// but with nicer error message.
    #[unstable]
    pub unsafe fn current_unwrap(&mut self) -> &mut T {
        match self.current() {
            None => {
                use std::intrinsics::get_tydesc;
                let name = (*get_tydesc::<T>()).name;
                panic!("No current `{}` is set", name);
            }
            Some(x) => x
        }
    }
}

impl<T: 'static> Deref for Current<T> {
    type Target = T;

    #[inline(always)]
    fn deref<'a>(&'a self) -> &'a T {
        use std::mem::transmute;
        unsafe {
            // Current does not contain anything,
            // so it is safe to transmute to mutable.
            transmute::<_, &'a mut Current<T>>(self).current_unwrap()
        }
    }
}

impl<T: 'static> DerefMut for Current<T> {
    #[inline(always)]
    fn deref_mut<'a>(&'a mut self) -> &'a mut T {
        unsafe { self.current_unwrap() }
    }
}
<commit_msg>Upgraded to latest Rust<commit_after>#![deny(missing_docs)]
#![feature(unsafe_destructor)]
#![unstable]
#![allow(unstable)]

//! A library for setting current values for stack scope,
//! such as application structure.

use std::cell::RefCell;
use std::intrinsics::TypeId;
use std::collections::HashMap;
use std::collections::hash_map::Entry::{ Occupied, Vacant };
use std::ops::{ Deref, DerefMut };

// Stores the current pointers for concrete types.
thread_local!(static KEY_CURRENT: RefCell<HashMap<TypeId, usize>>
    = RefCell::new(HashMap::new()));

/// Puts back the previous current pointer.
#[unstable]
pub struct CurrentGuard<'a, T: 'a> {
    _val: &'a mut T,
    old_ptr: Option<usize>
}

#[unstable]
impl<'a, T: 'static> CurrentGuard<'a, T> {
    /// Creates a new current guard.
    #[unstable]
    pub fn new(val: &mut T) -> CurrentGuard<T> {
        let id = TypeId::of::<T>();
        let ptr = val as *mut T as usize;
        let old_ptr = KEY_CURRENT.with(|current| {
            match current.borrow_mut().entry(id) {
                Occupied(mut entry) => Some(entry.insert(ptr)),
                Vacant(entry) => {
                    entry.insert(ptr);
                    None
                }
            }
        });
        CurrentGuard { old_ptr: old_ptr, _val: val }
    }
}

#[unsafe_destructor]
impl<'a, T: 'static> Drop for CurrentGuard<'a, T> {
    fn drop(&mut self) {
        let id = TypeId::of::<T>();
        match self.old_ptr {
            None => {
                KEY_CURRENT.with(|current| {
                    current.borrow_mut().remove(&id);
                });
                return;
            }
            Some(old_ptr) => {
                KEY_CURRENT.with(|current| {
                    match current.borrow_mut().entry(id) {
                        Occupied(mut entry) => { entry.insert(old_ptr); }
                        Vacant(entry) => { entry.insert(old_ptr); }
                    };
                });
            }
        };
    }
}

/// The current value of a type.
#[unstable]
pub struct Current<T>(());

#[unstable]
impl<T: 'static> Current<T> {
    /// Creates a new current object
    #[unstable]
    pub unsafe fn new() -> Current<T> { Current(()) }

    /// Gets mutable reference to current object.
    /// Requires mutable reference to prevent access to globals in safe code,
    /// and to prevent mutable borrows of same value in scope.
    /// Is unsafe because returned reference inherits lifetime from argument.
    #[unstable]
    pub unsafe fn current(&mut self) -> Option<&mut T> {
        use std::mem::transmute;
        let id = TypeId::of::<T>();
        let ptr: Option<usize> = KEY_CURRENT.with(|current| {
                current.borrow().get(&id).map(|id| *id)
            });
        let ptr = match ptr { None => { return None; } Some(x) => x };
        Some(transmute(ptr as *mut T))
    }

    /// Unwraps mutable reference to current object,
    /// but with nicer error message.
    #[unstable]
    pub unsafe fn current_unwrap(&mut self) -> &mut T {
        match self.current() {
            None => {
                use std::intrinsics::get_tydesc;
                let name = (*get_tydesc::<T>()).name;
                panic!("No current `{}` is set", name);
            }
            Some(x) => x
        }
    }
}

impl<T: 'static> Deref for Current<T> {
    type Target = T;

    #[inline(always)]
    fn deref<'a>(&'a self) -> &'a T {
        use std::mem::transmute;
        unsafe {
            // Current does not contain anything,
            // so it is safe to transmute to mutable.
            transmute::<_, &'a mut Current<T>>(self).current_unwrap()
        }
    }
}

impl<T: 'static> DerefMut for Current<T> {
    #[inline(always)]
    fn deref_mut<'a>(&'a mut self) -> &'a mut T {
        unsafe { self.current_unwrap() }
    }
}
<|endoftext|>


<commit_before>//! Actix web is a small, pragmatic, and extremely fast web framework
//! for Rust.
//!
//! ```rust
//! use actix_web::{web, App, Responder, HttpServer};
//! # use std::thread;
//!
//! fn index(info: web::Path<(String, u32)>) -> impl Responder {
//!     format!("Hello {}! id:{}", info.0, info.1)
//! }
//!
//! fn main() -> std::io::Result<()> {
//!     # thread::spawn(|| {
//!     HttpServer::new(|| App::new().service(
//!         web::resource("/{name}/{id}/index.html").to(index))
//!     )
//!         .bind("127.0.0.1:8080")?
//!         .run()
//!     # });
//!     # Ok(())
//! }
//! ```
//!
//! ## Documentation & community resources
//!
//! Besides the API documentation (which you are currently looking
//! at!), several other resources are available:
//!
//! * [User Guide](https://actix.rs/docs/)
//! * [Chat on gitter](https://gitter.im/actix/actix)
//! * [GitHub repository](https://github.com/actix/actix-web)
//! * [Cargo package](https://crates.io/crates/actix-web)
//!
//! To get started navigating the API documentation you may want to
//! consider looking at the following pages:
//!
//! * [App](struct.App.html): This struct represents an actix-web
//!   application and is used to configure routes and other common
//!   settings.
//!
//! * [HttpServer](struct.HttpServer.html): This struct
//!   represents an HTTP server instance and is used to instantiate and
//!   configure servers.
//!
//! * [HttpRequest](struct.HttpRequest.html) and
//!   [HttpResponse](struct.HttpResponse.html): These structs
//!   represent HTTP requests and responses and expose various methods
//!   for inspecting, creating and otherwise utilizing them.
//!
//! ## Features
//!
//! * Supported *HTTP/1.x* and *HTTP/2.0* protocols
//! * Streaming and pipelining
//! * Keep-alive and slow requests handling
//! * `WebSockets` server/client
//! * Transparent content compression/decompression (br, gzip, deflate)
//! * Configurable request routing
//! * Multipart streams
//! * SSL support with OpenSSL or `native-tls`
//! * Middlewares (`Logger`, `Session`, `CORS`, `CSRF`, `DefaultHeaders`)
//! * Supports [Actix actor framework](https://github.com/actix/actix)
//! * Supported Rust version: 1.32 or later
//!
//! ## Package feature
//!
//! * `tls` - enables ssl support via `native-tls` crate
//! * `ssl` - enables ssl support via `openssl` crate, supports `http/2`
//! * `rust-tls` - enables ssl support via `rustls` crate, supports `http/2`
//! * `cookies` - enables cookies support, includes `ring` crate as
//!   dependency
//! * `brotli` - enables `brotli` compression support, requires `c`
//!   compiler
//! * `flate2-c` - enables `gzip`, `deflate` compression support, requires
//!   `c` compiler
//! * `flate2-rust` - experimental rust based implementation for
//!   `gzip`, `deflate` compression.
//!
#![allow(clippy::type_complexity, clippy::new_without_default)]

mod app;
mod app_service;
mod config;
mod data;
pub mod error;
mod extract;
pub mod guard;
mod handler;
mod info;
pub mod middleware;
mod request;
mod resource;
mod responder;
mod rmap;
mod route;
mod scope;
mod server;
mod service;
pub mod test;
mod types;

#[allow(unused_imports)]
#[macro_use]
extern crate actix_web_codegen;

#[doc(hidden)]
pub use actix_web_codegen::*;

// re-export for convenience
pub use actix_http::Response as HttpResponse;
pub use actix_http::{http, Error, HttpMessage, ResponseError, Result};

pub use crate::app::App;
pub use crate::extract::FromRequest;
pub use crate::request::HttpRequest;
pub use crate::resource::Resource;
pub use crate::responder::{Either, Responder};
pub use crate::route::Route;
pub use crate::server::HttpServer;

pub mod dev {
    //! The `actix-web` prelude for library developers
    //!
    //! The purpose of this module is to alleviate imports of many common actix
    //! traits by adding a glob import to the top of actix heavy modules:
    //!
    //! ```
    //! # #![allow(unused_imports)]
    //! use actix_web::dev::*;
    //! ```

    pub use crate::app::AppRouter;
    pub use crate::config::{AppConfig, ServiceConfig};
    pub use crate::info::ConnectionInfo;
    pub use crate::rmap::ResourceMap;
    pub use crate::service::{
        HttpServiceFactory, ServiceFromRequest, ServiceRequest, ServiceResponse,
    };
    pub use crate::types::form::UrlEncoded;
    pub use crate::types::json::JsonBody;
    pub use crate::types::payload::HttpMessageBody;
    pub use crate::types::readlines::Readlines;

    pub use actix_http::body::{Body, BodyLength, MessageBody, ResponseBody};
    pub use actix_http::ResponseBuilder as HttpResponseBuilder;
    pub use actix_http::{
        Extensions, Head, Payload, PayloadStream, RequestHead, ResponseHead,
    };
    pub use actix_router::{Path, ResourceDef, ResourcePath, Url};
    pub use actix_server::Server;

    pub(crate) fn insert_slash(path: &str) -> String {
        let mut path = path.to_owned();
        if !path.is_empty() && !path.starts_with('/') {
            path.insert(0, '/');
        };
        path
    }
}

pub mod web {
    //! Various types
    use actix_http::{http::Method, Response};
    use actix_rt::blocking;
    use futures::{Future, IntoFuture};

    pub use actix_http::Response as HttpResponse;
    pub use bytes::{Bytes, BytesMut};

    use crate::error::{BlockingError, Error};
    use crate::extract::FromRequest;
    use crate::handler::{AsyncFactory, Factory};
    use crate::resource::Resource;
    use crate::responder::Responder;
    use crate::route::Route;
    use crate::scope::Scope;

    pub use crate::data::{Data, RouteData};
    pub use crate::request::HttpRequest;
    pub use crate::types::*;

    /// Create resource for a specific path.
    ///
    /// Resources may have variable path segments. For example, a
    /// resource with the path `/a/{name}/c` would match all incoming
    /// requests with paths such as `/a/b/c`, `/a/1/c`, or `/a/etc/c`.
    ///
    /// A variable segment is specified in the form `{identifier}`,
    /// where the identifier can be used later in a request handler to
    /// access the matched value for that segment. This is done by
    /// looking up the identifier in the `Params` object returned by
    /// `HttpRequest.match_info()` method.
    ///
    /// By default, each segment matches the regular expression `[^{}/]+`.
    ///
    /// You can also specify a custom regex in the form `{identifier:regex}`:
    ///
    /// For instance, to route `GET`-requests on any route matching
    /// `/users/{userid}/{friend}` and store `userid` and `friend` in
    /// the exposed `Params` object:
    ///
    /// ```rust
    /// # extern crate actix_web;
    /// use actix_web::{web, http, App, HttpResponse};
    ///
    /// fn main() {
    ///     let app = App::new().service(
    ///         web::resource("/users/{userid}/{friend}")
    ///             .route(web::get().to(|| HttpResponse::Ok()))
    ///             .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
    ///     );
    /// }
    /// ```
    pub fn resource
(path: &str) -> Resource
 {
        Resource::new(path)
    }

    /// Configure scope for common root path.
    ///
    /// Scopes collect multiple paths under a common path prefix.
    /// Scope path can contain variable path segments as resources.
    ///
    /// ```rust
    /// # extern crate actix_web;
    /// use actix_web::{web, App, HttpRequest, HttpResponse};
    ///
    /// fn main() {
    ///     let app = App::new().service(
    ///         web::scope("/{project_id}")
    ///             .service(web::resource("/path1").to(|| HttpResponse::Ok()))
    ///             .service(web::resource("/path2").to(|| HttpResponse::Ok()))
    ///             .service(web::resource("/path3").to(|| HttpResponse::MethodNotAllowed()))
    ///     );
    /// }
    /// ```
    ///
    /// In the above example, three routes get added:
    ///  * /{project_id}/path1
    ///  * /{project_id}/path2
    ///  * /{project_id}/path3
    ///
    pub fn scope
(path: &str) -> Scope
 {
        Scope::new(path)
    }

    /// Create *route* without configuration.
    pub fn route
() -> Route
 {
        Route::new()
    }

    /// Create *route* with `GET` method guard.
    pub fn get
() -> Route
 {
        Route::new().method(Method::GET)
    }

    /// Create *route* with `POST` method guard.
    pub fn post
() -> Route
 {
        Route::new().method(Method::POST)
    }

    /// Create *route* with `PUT` method guard.
    pub fn put
() -> Route
 {
        Route::new().method(Method::PUT)
    }

    /// Create *route* with `PATCH` method guard.
    pub fn patch
() -> Route
 {
        Route::new().method(Method::PATCH)
    }

    /// Create *route* with `DELETE` method guard.
    pub fn delete
() -> Route
 {
        Route::new().method(Method::DELETE)
    }

    /// Create *route* with `HEAD` method guard.
    pub fn head
() -> Route
 {
        Route::new().method(Method::HEAD)
    }

    /// Create *route* and add method guard.
    pub fn method
(method: Method) -> Route
 {
        Route::new().method(method)
    }

    /// Create a new route and add handler.
    ///
    /// ```rust
    /// use actix_web::{web, App, HttpResponse};
    ///
    /// fn index() -> HttpResponse {
    ///    unimplemented!()
    /// }
    ///
    /// App::new().service(
    ///     web::resource("/").route(
    ///         web::to(index))
    /// );
    /// ```
    pub fn to<F, I, R, P: 'static>(handler: F) -> Route

    where
        F: Factory + 'static,
        I: FromRequest
 + 'static,
        R: Responder + 'static,
    {
        Route::new().to(handler)
    }

    /// Create a new route and add async handler.
    ///
    /// ```rust
    /// use actix_web::{web, App, HttpResponse, Error};
    ///
    /// fn index() -> impl futures::Future<Item=HttpResponse, Error=Error> {
    ///     futures::future::ok(HttpResponse::Ok().finish())
    /// }
    ///
    /// App::new().service(web::resource("/").route(
    ///     web::to_async(index))
    /// );
    /// ```
    pub fn to_async<F, I, R, P: 'static>(handler: F) -> Route

    where
        F: AsyncFactory,
        I: FromRequest
 + 'static,
        R: IntoFuture + 'static,
        R::Item: Into<Response>,
        R::Error: Into<Error>,
    {
        Route::new().to_async(handler)
    }

    /// Execute blocking function on a thread pool, returns future that resolves
    /// to result of the function execution.
    pub fn block<F, I, E>(f: F) -> impl Future<Item = I, Error = BlockingError<E>>
    where
        F: FnOnce() -> Result + Send + 'static,
        I: Send + 'static,
        E: Send + std::fmt::Debug + 'static,
    {
        blocking::run(f).from_err()
    }
}
<commit_msg>export Scope<commit_after>//! Actix web is a small, pragmatic, and extremely fast web framework
//! for Rust.
//!
//! ```rust
//! use actix_web::{web, App, Responder, HttpServer};
//! # use std::thread;
//!
//! fn index(info: web::Path<(String, u32)>) -> impl Responder {
//!     format!("Hello {}! id:{}", info.0, info.1)
//! }
//!
//! fn main() -> std::io::Result<()> {
//!     # thread::spawn(|| {
//!     HttpServer::new(|| App::new().service(
//!         web::resource("/{name}/{id}/index.html").to(index))
//!     )
//!         .bind("127.0.0.1:8080")?
//!         .run()
//!     # });
//!     # Ok(())
//! }
//! ```
//!
//! ## Documentation & community resources
//!
//! Besides the API documentation (which you are currently looking
//! at!), several other resources are available:
//!
//! * [User Guide](https://actix.rs/docs/)
//! * [Chat on gitter](https://gitter.im/actix/actix)
//! * [GitHub repository](https://github.com/actix/actix-web)
//! * [Cargo package](https://crates.io/crates/actix-web)
//!
//! To get started navigating the API documentation you may want to
//! consider looking at the following pages:
//!
//! * [App](struct.App.html): This struct represents an actix-web
//!   application and is used to configure routes and other common
//!   settings.
//!
//! * [HttpServer](struct.HttpServer.html): This struct
//!   represents an HTTP server instance and is used to instantiate and
//!   configure servers.
//!
//! * [HttpRequest](struct.HttpRequest.html) and
//!   [HttpResponse](struct.HttpResponse.html): These structs
//!   represent HTTP requests and responses and expose various methods
//!   for inspecting, creating and otherwise utilizing them.
//!
//! ## Features
//!
//! * Supported *HTTP/1.x* and *HTTP/2.0* protocols
//! * Streaming and pipelining
//! * Keep-alive and slow requests handling
//! * `WebSockets` server/client
//! * Transparent content compression/decompression (br, gzip, deflate)
//! * Configurable request routing
//! * Multipart streams
//! * SSL support with OpenSSL or `native-tls`
//! * Middlewares (`Logger`, `Session`, `CORS`, `CSRF`, `DefaultHeaders`)
//! * Supports [Actix actor framework](https://github.com/actix/actix)
//! * Supported Rust version: 1.32 or later
//!
//! ## Package feature
//!
//! * `tls` - enables ssl support via `native-tls` crate
//! * `ssl` - enables ssl support via `openssl` crate, supports `http/2`
//! * `rust-tls` - enables ssl support via `rustls` crate, supports `http/2`
//! * `cookies` - enables cookies support, includes `ring` crate as
//!   dependency
//! * `brotli` - enables `brotli` compression support, requires `c`
//!   compiler
//! * `flate2-c` - enables `gzip`, `deflate` compression support, requires
//!   `c` compiler
//! * `flate2-rust` - experimental rust based implementation for
//!   `gzip`, `deflate` compression.
//!
#![allow(clippy::type_complexity, clippy::new_without_default)]

mod app;
mod app_service;
mod config;
mod data;
pub mod error;
mod extract;
pub mod guard;
mod handler;
mod info;
pub mod middleware;
mod request;
mod resource;
mod responder;
mod rmap;
mod route;
mod scope;
mod server;
mod service;
pub mod test;
mod types;

#[allow(unused_imports)]
#[macro_use]
extern crate actix_web_codegen;

#[doc(hidden)]
pub use actix_web_codegen::*;

// re-export for convenience
pub use actix_http::Response as HttpResponse;
pub use actix_http::{http, Error, HttpMessage, ResponseError, Result};

pub use crate::app::App;
pub use crate::extract::FromRequest;
pub use crate::request::HttpRequest;
pub use crate::resource::Resource;
pub use crate::responder::{Either, Responder};
pub use crate::route::Route;
pub use crate::scope::Scope;
pub use crate::server::HttpServer;

pub mod dev {
    //! The `actix-web` prelude for library developers
    //!
    //! The purpose of this module is to alleviate imports of many common actix
    //! traits by adding a glob import to the top of actix heavy modules:
    //!
    //! ```
    //! # #![allow(unused_imports)]
    //! use actix_web::dev::*;
    //! ```

    pub use crate::app::AppRouter;
    pub use crate::config::{AppConfig, ServiceConfig};
    pub use crate::info::ConnectionInfo;
    pub use crate::rmap::ResourceMap;
    pub use crate::service::{
        HttpServiceFactory, ServiceFromRequest, ServiceRequest, ServiceResponse,
    };
    pub use crate::types::form::UrlEncoded;
    pub use crate::types::json::JsonBody;
    pub use crate::types::payload::HttpMessageBody;
    pub use crate::types::readlines::Readlines;

    pub use actix_http::body::{Body, BodyLength, MessageBody, ResponseBody};
    pub use actix_http::ResponseBuilder as HttpResponseBuilder;
    pub use actix_http::{
        Extensions, Head, Payload, PayloadStream, RequestHead, ResponseHead,
    };
    pub use actix_router::{Path, ResourceDef, ResourcePath, Url};
    pub use actix_server::Server;

    pub(crate) fn insert_slash(path: &str) -> String {
        let mut path = path.to_owned();
        if !path.is_empty() && !path.starts_with('/') {
            path.insert(0, '/');
        };
        path
    }
}

pub mod web {
    //! Various types
    use actix_http::{http::Method, Response};
    use actix_rt::blocking;
    use futures::{Future, IntoFuture};

    pub use actix_http::Response as HttpResponse;
    pub use bytes::{Bytes, BytesMut};

    use crate::error::{BlockingError, Error};
    use crate::extract::FromRequest;
    use crate::handler::{AsyncFactory, Factory};
    use crate::resource::Resource;
    use crate::responder::Responder;
    use crate::route::Route;
    use crate::scope::Scope;

    pub use crate::data::{Data, RouteData};
    pub use crate::request::HttpRequest;
    pub use crate::types::*;

    /// Create resource for a specific path.
    ///
    /// Resources may have variable path segments. For example, a
    /// resource with the path `/a/{name}/c` would match all incoming
    /// requests with paths such as `/a/b/c`, `/a/1/c`, or `/a/etc/c`.
    ///
    /// A variable segment is specified in the form `{identifier}`,
    /// where the identifier can be used later in a request handler to
    /// access the matched value for that segment. This is done by
    /// looking up the identifier in the `Params` object returned by
    /// `HttpRequest.match_info()` method.
    ///
    /// By default, each segment matches the regular expression `[^{}/]+`.
    ///
    /// You can also specify a custom regex in the form `{identifier:regex}`:
    ///
    /// For instance, to route `GET`-requests on any route matching
    /// `/users/{userid}/{friend}` and store `userid` and `friend` in
    /// the exposed `Params` object:
    ///
    /// ```rust
    /// # extern crate actix_web;
    /// use actix_web::{web, http, App, HttpResponse};
    ///
    /// fn main() {
    ///     let app = App::new().service(
    ///         web::resource("/users/{userid}/{friend}")
    ///             .route(web::get().to(|| HttpResponse::Ok()))
    ///             .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
    ///     );
    /// }
    /// ```
    pub fn resource
(path: &str) -> Resource
 {
        Resource::new(path)
    }

    /// Configure scope for common root path.
    ///
    /// Scopes collect multiple paths under a common path prefix.
    /// Scope path can contain variable path segments as resources.
    ///
    /// ```rust
    /// # extern crate actix_web;
    /// use actix_web::{web, App, HttpRequest, HttpResponse};
    ///
    /// fn main() {
    ///     let app = App::new().service(
    ///         web::scope("/{project_id}")
    ///             .service(web::resource("/path1").to(|| HttpResponse::Ok()))
    ///             .service(web::resource("/path2").to(|| HttpResponse::Ok()))
    ///             .service(web::resource("/path3").to(|| HttpResponse::MethodNotAllowed()))
    ///     );
    /// }
    /// ```
    ///
    /// In the above example, three routes get added:
    ///  * /{project_id}/path1
    ///  * /{project_id}/path2
    ///  * /{project_id}/path3
    ///
    pub fn scope
(path: &str) -> Scope
 {
        Scope::new(path)
    }

    /// Create *route* without configuration.
    pub fn route
() -> Route
 {
        Route::new()
    }

    /// Create *route* with `GET` method guard.
    pub fn get
() -> Route
 {
        Route::new().method(Method::GET)
    }

    /// Create *route* with `POST` method guard.
    pub fn post
() -> Route
 {
        Route::new().method(Method::POST)
    }

    /// Create *route* with `PUT` method guard.
    pub fn put
() -> Route
 {
        Route::new().method(Method::PUT)
    }

    /// Create *route* with `PATCH` method guard.
    pub fn patch
() -> Route
 {
        Route::new().method(Method::PATCH)
    }

    /// Create *route* with `DELETE` method guard.
    pub fn delete
() -> Route
 {
        Route::new().method(Method::DELETE)
    }

    /// Create *route* with `HEAD` method guard.
    pub fn head
() -> Route
 {
        Route::new().method(Method::HEAD)
    }

    /// Create *route* and add method guard.
    pub fn method
(method: Method) -> Route
 {
        Route::new().method(method)
    }

    /// Create a new route and add handler.
    ///
    /// ```rust
    /// use actix_web::{web, App, HttpResponse};
    ///
    /// fn index() -> HttpResponse {
    ///    unimplemented!()
    /// }
    ///
    /// App::new().service(
    ///     web::resource("/").route(
    ///         web::to(index))
    /// );
    /// ```
    pub fn to<F, I, R, P: 'static>(handler: F) -> Route

    where
        F: Factory + 'static,
        I: FromRequest
 + 'static,
        R: Responder + 'static,
    {
        Route::new().to(handler)
    }

    /// Create a new route and add async handler.
    ///
    /// ```rust
    /// use actix_web::{web, App, HttpResponse, Error};
    ///
    /// fn index() -> impl futures::Future<Item=HttpResponse, Error=Error> {
    ///     futures::future::ok(HttpResponse::Ok().finish())
    /// }
    ///
    /// App::new().service(web::resource("/").route(
    ///     web::to_async(index))
    /// );
    /// ```
    pub fn to_async<F, I, R, P: 'static>(handler: F) -> Route

    where
        F: AsyncFactory,
        I: FromRequest
 + 'static,
        R: IntoFuture + 'static,
        R::Item: Into<Response>,
        R::Error: Into<Error>,
    {
        Route::new().to_async(handler)
    }

    /// Execute blocking function on a thread pool, returns future that resolves
    /// to result of the function execution.
    pub fn block<F, I, E>(f: F) -> impl Future<Item = I, Error = BlockingError<E>>
    where
        F: FnOnce() -> Result + Send + 'static,
        I: Send + 'static,
        E: Send + std::fmt::Debug + 'static,
    {
        blocking::run(f).from_err()
    }
}
<|endoftext|>


<commit_before>#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<commit_msg>Deny missing docs<commit_after>#![deny(missing_docs)]
//! An encoder and decoder for FITS images.
//!
//! The *Flexible Image Transport System* ([FITS][fits]) is
//! > an open standard defining a digital file format useful for storage,
//! > transmission and processing of scientific and other images.

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<|endoftext|>


<commit_before>//! A simple, cliché example demonstrating structure and syntax.

#![allow(clippy::non_ascii_literal)]

#[macro_use]
extern crate seed;

use seed::prelude::*;

mod pages;

#[derive(Copy, Clone)]
enum Page {
    Home,
    ContactUs,
    /*Faq,
    Downloads,
    Status,
    NumberCruncher,
    PrimalityChecker,
    PrimeNumbersArchive,
    MersennePrimeArchive,
    FermatArchive,
    PerfectArchive,
    FibonacciArchive*/
    //Article(article::slug::Slug),
}

// Model
struct Model {
    page: Page,
}

// Setup a default here, for initialization later.
impl Default for Model {
    fn default() -> Self {
        Self {
            page: Page::Home,
        }
    }
}

// Update
#[derive(Clone)]
enum Msg {
    ChangePage(Page),
}

/// The sole source of updating the model
fn update(msg: Msg, model: &mut Model, _: &mut Orders<Msg>) {
    match msg {
        Msg::ChangePage(page) => model.page = page
    }
}

// View

/// A simple component.
/*fn success_level(clicks: i32) -> Node<Msg> {
    let descrip = match clicks {
        0..=5 => "Not very many 🙁",
        6..=9 => "I got my first real six-string 😐",
        10..=11 => "Spinal Tap 🙂",
        _ => "Double pendulum 🙃",
    };
    p![descrip]
}*/

/// The top-level component we pass to the virtual dom. Must accept the model as its
/// only argument, and output has to implement trait `ElContainer`.
fn view(model: &Model) -> impl View<Msg> {

    // Attrs, Style, Events, and children may be defined separately.
    let outer_style = style! {
            "display" => "flex",
            "flex-direction" => "column",
            "text-align" => "center",
    };

    match model.page {
        Page::Home => div![
            outer_style,
            h1!["The Grand Total"],
            div![
                style! {
                    // Example of conditional logic in a style.
                    "color" => "gray";
                    "border" => "2px solid #004422";
                    "padding" => unit!(20, px);
                },
                // We can use normal Rust code and comments in the view.
                // Optionally-displaying an element, and lifecycle hooks
            ],
            a!["Contact Us", attrs!{At::Href => "/contactus/"} ]
        ],
        _ => div![]
    }
}

impl ToString for Page {
    fn to_string(&self) -> String {
        // Eg for url routing
        match self {
            Page::Home => "home".into(),
            Page::ContactUs => "contactus".into(),
        }
    }
}

fn routes(url: seed::Url) -> Msg {
    if url.path.is_empty() {
        return Msg::ChangePage(Page::Home)
    }

    match url.path[0].as_ref() {
        "guide" => {
            // Determine if we are at the main page, or a subpage
            match url.path.get(1).as_ref() {
                Some(page) => Msg::ChangePage(Page::Home),
                None => Msg::ChangePage(Page::Home)
            }
        },
        "contactus" => Msg::ChangePage(Page::ContactUs),
        _ => Msg::ChangePage(Page::Home)
    }
}

#[wasm_bindgen(start)]
pub fn render() {
    seed::App::build(Model::default(), update, view)
        .mount("app")
        .routes(routes)
        //.window_events(window_events)
        .finish()
        .run();
}<commit_msg>Removed noted out code<commit_after>#![allow(clippy::non_ascii_literal)]

#[macro_use]
extern crate seed;

use seed::prelude::*;

mod pages;

#[derive(Copy, Clone)]
enum Page {
    Home,
    ContactUs,
    /*Faq,
    Downloads,
    Status,
    NumberCruncher,
    PrimalityChecker,
    PrimeNumbersArchive,
    MersennePrimeArchive,
    FermatArchive,
    PerfectArchive,
    FibonacciArchive*/
    //Article(article::slug::Slug),
}

// Model
struct Model {
    page: Page,
}

// Setup a default here, for initialization later.
impl Default for Model {
    fn default() -> Self {
        Self {
            page: Page::Home,
        }
    }
}

// Update
#[derive(Clone)]
enum Msg {
    ChangePage(Page),
}

/// The sole source of updating the model
fn update(msg: Msg, model: &mut Model, _: &mut Orders<Msg>) {
    match msg {
        Msg::ChangePage(page) => model.page = page
    }
}

/// The top-level component we pass to the virtual dom. Must accept the model as its
/// only argument, and output has to implement trait `ElContainer`.
fn view(model: &Model) -> impl View<Msg> {

    // Attrs, Style, Events, and children may be defined separately.
    let outer_style = style! {
            "display" => "flex",
            "flex-direction" => "column",
            "text-align" => "center",
    };

    match model.page {
        Page::Home => div![
            outer_style,
            h1!["The Grand Total"],
            div![
                style! {
                    // Example of conditional logic in a style.
                    "color" => "gray";
                    "border" => "2px solid #004422";
                    "padding" => unit!(20, px);
                },
                // We can use normal Rust code and comments in the view.
                // Optionally-displaying an element, and lifecycle hooks
            ],
            a!["Contact Us", attrs!{At::Href => "/contactus/"} ]
        ],
        _ => div![]
    }
}

impl ToString for Page {
    fn to_string(&self) -> String {
        // Eg for url routing
        match self {
            Page::Home => "home".into(),
            Page::ContactUs => "contactus".into(),
        }
    }
}

fn routes(url: seed::Url) -> Msg {
    if url.path.is_empty() {
        return Msg::ChangePage(Page::Home)
    }

    match url.path[0].as_ref() {
        "guide" => {
            // Determine if we are at the main page, or a subpage
            match url.path.get(1).as_ref() {
                Some(page) => Msg::ChangePage(Page::Home),
                None => Msg::ChangePage(Page::Home)
            }
        },
        "contactus" => Msg::ChangePage(Page::ContactUs),
        _ => Msg::ChangePage(Page::Home)
    }
}

#[wasm_bindgen(start)]
pub fn render() {
    seed::App::build(Model::default(), update, view)
        .mount("app")
        .routes(routes)
        //.window_events(window_events)
        .finish()
        .run();
}<|endoftext|>


<commit_before>#![feature(unsafe_destructor)]
#![feature(globs)]
#![unstable]

extern crate libc;

pub use events::*;

#[cfg(windows)]
use winimpl = win32;
#[cfg(unix)]
use winimpl = x11;

#[cfg(windows)]
mod win32;
#[cfg(unix)]
mod x11;

#[allow(dead_code)]
//mod egl;

mod events;

/// Identifier for a monitor.
pub struct MonitorID(winimpl::MonitorID);

/// Object that allows you to build windows.
pub struct WindowBuilder {
    dimensions: Option<(uint, uint)>,
    title: String,
    monitor: Option<winimpl::MonitorID>,
    gl_version: Option<(uint, uint)>,
}

impl WindowBuilder {
    /// Initializes a new `WindowBuilder` with default values.
    pub fn new() -> WindowBuilder {
        WindowBuilder {
            dimensions: None,
            title: String::new(),
            monitor: None,
            gl_version: None,
        }
    }

    /// Requests the window to be of specific dimensions.
    ///
    /// Width and height are in pixels.
    pub fn with_dimensions(mut self, width: uint, height: uint) -> WindowBuilder {
        self.dimensions = Some((width, height));
        self
    }

    /// Requests a specific title for the window.
    pub fn with_title(mut self, title: String) -> WindowBuilder {
        self.title = title;
        self
    }

    /// Requests fullscreen mode.
    ///
    /// If you don't specify dimensions for the window, it will match the monitor's.
    pub fn with_fullscreen(mut self, monitor: MonitorID) -> WindowBuilder {
        let MonitorID(monitor) = monitor;
        self.monitor = Some(monitor);
        self
    }

    /// Requests to use a specific OpenGL version.
    ///
    /// Version is a (major, minor) pair. For example to request OpenGL 3.3
    ///  you would pass `(3, 3)`.
    pub fn with_gl_version(mut self, version: (uint, uint)) -> WindowBuilder {
        self.gl_version = Some(version);
        self
    }

    /// Builds the window.
    ///
    /// Error should be very rare and only occur in case of permission denied, incompatible system,
    ///  out of memory, etc.
    pub fn build(mut self) -> Result<Window, String> {
        // resizing the window to the dimensions of the monitor when fullscreen
        if self.dimensions.is_none() && self.monitor.is_some() {
            self.dimensions = Some(self.monitor.as_ref().unwrap().get_dimensions())
        }

        // default dimensions
        if self.dimensions.is_none() {
            self.dimensions = Some((1024, 768));
        }

        // building
        winimpl::Window::new(self).map(|w| Window { window: w })
    }
}

/// Represents an OpenGL context and the Window or environment around it.
///
/// # Example
///
/// ```
/// let window = Window::new().unwrap();
///
/// unsafe { window.make_current() };
///
/// loop {
///     for event in window.poll_events() {
///             // process events here
///             _ => ()
///         }
///     }
///
///     // draw everything here
///
///     window.swap_buffers();
///     std::io::timer::sleep(17);
/// }
/// ```
pub struct Window {
    window: winimpl::Window,
}

impl Window {
    /// Creates a new OpenGL context, and a Window for platforms where this is appropriate.
    ///
    /// This function is equivalent to `WindowBuilder::new().build()`.
    ///
    /// Error should be very rare and only occur in case of permission denied, incompatible system,
    ///  out of memory, etc.
    #[inline]
    pub fn new() -> Result<Window, String> {
        let builder = WindowBuilder::new();
        builder.build()
    }

    /// Returns true if the window has previously been closed by the user.
    #[inline]
    pub fn is_closed(&self) -> bool {
        self.window.is_closed()
    }

    /// Returns true if the window has previously been closed by the user.
    #[inline]
    #[deprecated = "Use is_closed instead"]
    pub fn should_close(&self) -> bool {
        self.is_closed()
    }

    /// Modifies the title of the window.
    ///
    /// This is a no-op if the window has already been closed.
    #[inline]
    pub fn set_title(&self, title: &str) {
        self.window.set_title(title)
    }

    /// Returns the position of the top-left hand corner of the window relative to the
    ///  top-left hand corner of the desktop.
    ///
    /// Note that the top-left hand corner of the desktop is not necessarly the same as
    ///  the screen. If the user uses a desktop with multiple monitors, the top-left hand corner
    ///  of the desktop is the top-left hand corner of the monitor at the top-left of the desktop.
    ///
    /// The coordinates can be negative if the top-left hand corner of the window is outside
    ///  of the visible screen region.
    ///
    /// Returns `None` if the window no longer exists.
    #[inline]
    pub fn get_position(&self) -> Option<(int, int)> {
        self.window.get_position()
    }

    /// Modifies the position of the window.
    ///
    /// See `get_position` for more informations about the coordinates.
    ///
    /// This is a no-op if the window has already been closed.
    #[inline]
    pub fn set_position(&self, x: uint, y: uint) {
        self.window.set_position(x, y)
    }

    /// Returns the size in pixels of the client area of the window.
    ///
    /// The client area is the content of the window, excluding the title bar and borders.
    /// These are the dimensions of the frame buffer, and the dimensions that you should use
    ///  when you call `glViewport`.
    ///
    /// Returns `None` if the window no longer exists.
    #[inline]
    pub fn get_inner_size(&self) -> Option<(uint, uint)> {
        self.window.get_inner_size()
    }

    /// Returns the size in pixels of the window.
    ///
    /// These dimensions include title bar and borders. If you don't want these, you should use
    ///  use `get_inner_size` instead.
    ///
    /// Returns `None` if the window no longer exists.
    #[inline]
    pub fn get_outer_size(&self) -> Option<(uint, uint)> {
        self.window.get_outer_size()
    }

    /// Modifies the inner size of the window.
    ///
    /// See `get_inner_size` for more informations about the values.
    ///
    /// This is a no-op if the window has already been closed.
    #[inline]
    pub fn set_inner_size(&self, x: uint, y: uint) {
        self.window.set_inner_size(x, y)
    }

    /// Returns an iterator to all the events that are currently in the window's events queue.
    ///
    /// Contrary to `wait_events`, this function never blocks.
    #[inline]
    pub fn poll_events(&self) -> PollEventsIterator {
        PollEventsIterator { data: self.window.poll_events() }
    }

    /// Waits for an event, then returns an iterator to all the events that are currently
    ///  in the window's events queue.
    ///
    /// If there are no events in queue when you call the function,
    ///  this function will block until there is one.
    #[inline]
    pub fn wait_events(&self) -> WaitEventsIterator {
        WaitEventsIterator { data: self.window.wait_events() }
    }

    /// Sets the context as the current context.
    #[inline]
    #[experimental]
    pub unsafe fn make_current(&self) {
        self.window.make_current()
    }

    /// Returns the address of an OpenGL function.
    ///
    /// Contrary to `wglGetProcAddress`, all available OpenGL functions return an address.
    #[inline]
    pub fn get_proc_address(&self, addr: &str) -> *const () {
        self.window.get_proc_address(addr)
    }

    /// Swaps the buffers in case of double or triple buffering.
    ///
    /// You should call this function every time you have finished rendering, or the image
    ///  may not be displayed on the screen.
    #[inline]
    pub fn swap_buffers(&self) {
        self.window.swap_buffers()
    }
}

/// An iterator for the `poll_events` function.
// Implementation note: we retreive the list once, then serve each element by one by one.
// This may change in the future.
pub struct PollEventsIterator<'a> {
    data: Vec<Event>,
}

impl<'a> Iterator<Event> for PollEventsIterator<'a> {
    fn next(&mut self) -> Option<Event> {
        self.data.remove(0)
    }
}

/// An iterator for the `wait_events` function.
// Implementation note: we retreive the list once, then serve each element by one by one.
// This may change in the future.
pub struct WaitEventsIterator<'a> {
    data: Vec<Event>,
}

impl<'a> Iterator<Event> for WaitEventsIterator<'a> {
    fn next(&mut self) -> Option<Event> {
        self.data.remove(0)
    }
}

/// An iterator for the list of available monitors.
// Implementation note: we retreive the list once, then serve each element by one by one.
// This may change in the future.
pub struct AvailableMonitorsIter {
    data: Vec<winimpl::MonitorID>,
}

impl Iterator<MonitorID> for AvailableMonitorsIter {
    fn next(&mut self) -> Option<MonitorID> {
        self.data.remove(0).map(|id| MonitorID(id))
    }
}

/// Returns the list of all available monitors.
pub fn get_available_monitors() -> AvailableMonitorsIter {
    let data = winimpl::get_available_monitors();
    AvailableMonitorsIter{ data: data }
}

/// Returns the primary monitor of the system.
pub fn get_primary_monitor() -> MonitorID {
    MonitorID(winimpl::get_primary_monitor())
}

impl MonitorID {
    /// Returns a human-readable name of the monitor.
    pub fn get_name(&self) -> Option<String> {
        let &MonitorID(ref id) = self;
        id.get_name()
    }

    /// Returns the number of pixels currently displayed on the monitor.
    pub fn get_dimensions(&self) -> (uint, uint) {
        let &MonitorID(ref id) = self;
        id.get_dimensions()
    }
}
<commit_msg>Remove #[exprimental] from make_current<commit_after>#![feature(unsafe_destructor)]
#![feature(globs)]
#![unstable]

extern crate libc;

pub use events::*;

#[cfg(windows)]
use winimpl = win32;
#[cfg(unix)]
use winimpl = x11;

#[cfg(windows)]
mod win32;
#[cfg(unix)]
mod x11;

#[allow(dead_code)]
//mod egl;

mod events;

/// Identifier for a monitor.
pub struct MonitorID(winimpl::MonitorID);

/// Object that allows you to build windows.
pub struct WindowBuilder {
    dimensions: Option<(uint, uint)>,
    title: String,
    monitor: Option<winimpl::MonitorID>,
    gl_version: Option<(uint, uint)>,
}

impl WindowBuilder {
    /// Initializes a new `WindowBuilder` with default values.
    pub fn new() -> WindowBuilder {
        WindowBuilder {
            dimensions: None,
            title: String::new(),
            monitor: None,
            gl_version: None,
        }
    }

    /// Requests the window to be of specific dimensions.
    ///
    /// Width and height are in pixels.
    pub fn with_dimensions(mut self, width: uint, height: uint) -> WindowBuilder {
        self.dimensions = Some((width, height));
        self
    }

    /// Requests a specific title for the window.
    pub fn with_title(mut self, title: String) -> WindowBuilder {
        self.title = title;
        self
    }

    /// Requests fullscreen mode.
    ///
    /// If you don't specify dimensions for the window, it will match the monitor's.
    pub fn with_fullscreen(mut self, monitor: MonitorID) -> WindowBuilder {
        let MonitorID(monitor) = monitor;
        self.monitor = Some(monitor);
        self
    }

    /// Requests to use a specific OpenGL version.
    ///
    /// Version is a (major, minor) pair. For example to request OpenGL 3.3
    ///  you would pass `(3, 3)`.
    pub fn with_gl_version(mut self, version: (uint, uint)) -> WindowBuilder {
        self.gl_version = Some(version);
        self
    }

    /// Builds the window.
    ///
    /// Error should be very rare and only occur in case of permission denied, incompatible system,
    ///  out of memory, etc.
    pub fn build(mut self) -> Result<Window, String> {
        // resizing the window to the dimensions of the monitor when fullscreen
        if self.dimensions.is_none() && self.monitor.is_some() {
            self.dimensions = Some(self.monitor.as_ref().unwrap().get_dimensions())
        }

        // default dimensions
        if self.dimensions.is_none() {
            self.dimensions = Some((1024, 768));
        }

        // building
        winimpl::Window::new(self).map(|w| Window { window: w })
    }
}

/// Represents an OpenGL context and the Window or environment around it.
///
/// # Example
///
/// ```
/// let window = Window::new().unwrap();
///
/// unsafe { window.make_current() };
///
/// loop {
///     for event in window.poll_events() {
///             // process events here
///             _ => ()
///         }
///     }
///
///     // draw everything here
///
///     window.swap_buffers();
///     std::io::timer::sleep(17);
/// }
/// ```
pub struct Window {
    window: winimpl::Window,
}

impl Window {
    /// Creates a new OpenGL context, and a Window for platforms where this is appropriate.
    ///
    /// This function is equivalent to `WindowBuilder::new().build()`.
    ///
    /// Error should be very rare and only occur in case of permission denied, incompatible system,
    ///  out of memory, etc.
    #[inline]
    pub fn new() -> Result<Window, String> {
        let builder = WindowBuilder::new();
        builder.build()
    }

    /// Returns true if the window has previously been closed by the user.
    #[inline]
    pub fn is_closed(&self) -> bool {
        self.window.is_closed()
    }

    /// Returns true if the window has previously been closed by the user.
    #[inline]
    #[deprecated = "Use is_closed instead"]
    pub fn should_close(&self) -> bool {
        self.is_closed()
    }

    /// Modifies the title of the window.
    ///
    /// This is a no-op if the window has already been closed.
    #[inline]
    pub fn set_title(&self, title: &str) {
        self.window.set_title(title)
    }

    /// Returns the position of the top-left hand corner of the window relative to the
    ///  top-left hand corner of the desktop.
    ///
    /// Note that the top-left hand corner of the desktop is not necessarly the same as
    ///  the screen. If the user uses a desktop with multiple monitors, the top-left hand corner
    ///  of the desktop is the top-left hand corner of the monitor at the top-left of the desktop.
    ///
    /// The coordinates can be negative if the top-left hand corner of the window is outside
    ///  of the visible screen region.
    ///
    /// Returns `None` if the window no longer exists.
    #[inline]
    pub fn get_position(&self) -> Option<(int, int)> {
        self.window.get_position()
    }

    /// Modifies the position of the window.
    ///
    /// See `get_position` for more informations about the coordinates.
    ///
    /// This is a no-op if the window has already been closed.
    #[inline]
    pub fn set_position(&self, x: uint, y: uint) {
        self.window.set_position(x, y)
    }

    /// Returns the size in pixels of the client area of the window.
    ///
    /// The client area is the content of the window, excluding the title bar and borders.
    /// These are the dimensions of the frame buffer, and the dimensions that you should use
    ///  when you call `glViewport`.
    ///
    /// Returns `None` if the window no longer exists.
    #[inline]
    pub fn get_inner_size(&self) -> Option<(uint, uint)> {
        self.window.get_inner_size()
    }

    /// Returns the size in pixels of the window.
    ///
    /// These dimensions include title bar and borders. If you don't want these, you should use
    ///  use `get_inner_size` instead.
    ///
    /// Returns `None` if the window no longer exists.
    #[inline]
    pub fn get_outer_size(&self) -> Option<(uint, uint)> {
        self.window.get_outer_size()
    }

    /// Modifies the inner size of the window.
    ///
    /// See `get_inner_size` for more informations about the values.
    ///
    /// This is a no-op if the window has already been closed.
    #[inline]
    pub fn set_inner_size(&self, x: uint, y: uint) {
        self.window.set_inner_size(x, y)
    }

    /// Returns an iterator to all the events that are currently in the window's events queue.
    ///
    /// Contrary to `wait_events`, this function never blocks.
    #[inline]
    pub fn poll_events(&self) -> PollEventsIterator {
        PollEventsIterator { data: self.window.poll_events() }
    }

    /// Waits for an event, then returns an iterator to all the events that are currently
    ///  in the window's events queue.
    ///
    /// If there are no events in queue when you call the function,
    ///  this function will block until there is one.
    #[inline]
    pub fn wait_events(&self) -> WaitEventsIterator {
        WaitEventsIterator { data: self.window.wait_events() }
    }

    /// Sets the context as the current context.
    #[inline]
    pub unsafe fn make_current(&self) {
        self.window.make_current()
    }

    /// Returns the address of an OpenGL function.
    ///
    /// Contrary to `wglGetProcAddress`, all available OpenGL functions return an address.
    #[inline]
    pub fn get_proc_address(&self, addr: &str) -> *const () {
        self.window.get_proc_address(addr)
    }

    /// Swaps the buffers in case of double or triple buffering.
    ///
    /// You should call this function every time you have finished rendering, or the image
    ///  may not be displayed on the screen.
    #[inline]
    pub fn swap_buffers(&self) {
        self.window.swap_buffers()
    }
}

/// An iterator for the `poll_events` function.
// Implementation note: we retreive the list once, then serve each element by one by one.
// This may change in the future.
pub struct PollEventsIterator<'a> {
    data: Vec<Event>,
}

impl<'a> Iterator<Event> for PollEventsIterator<'a> {
    fn next(&mut self) -> Option<Event> {
        self.data.remove(0)
    }
}

/// An iterator for the `wait_events` function.
// Implementation note: we retreive the list once, then serve each element by one by one.
// This may change in the future.
pub struct WaitEventsIterator<'a> {
    data: Vec<Event>,
}

impl<'a> Iterator<Event> for WaitEventsIterator<'a> {
    fn next(&mut self) -> Option<Event> {
        self.data.remove(0)
    }
}

/// An iterator for the list of available monitors.
// Implementation note: we retreive the list once, then serve each element by one by one.
// This may change in the future.
pub struct AvailableMonitorsIter {
    data: Vec<winimpl::MonitorID>,
}

impl Iterator<MonitorID> for AvailableMonitorsIter {
    fn next(&mut self) -> Option<MonitorID> {
        self.data.remove(0).map(|id| MonitorID(id))
    }
}

/// Returns the list of all available monitors.
pub fn get_available_monitors() -> AvailableMonitorsIter {
    let data = winimpl::get_available_monitors();
    AvailableMonitorsIter{ data: data }
}

/// Returns the primary monitor of the system.
pub fn get_primary_monitor() -> MonitorID {
    MonitorID(winimpl::get_primary_monitor())
}

impl MonitorID {
    /// Returns a human-readable name of the monitor.
    pub fn get_name(&self) -> Option<String> {
        let &MonitorID(ref id) = self;
        id.get_name()
    }

    /// Returns the number of pixels currently displayed on the monitor.
    pub fn get_dimensions(&self) -> (uint, uint) {
        let &MonitorID(ref id) = self;
        id.get_dimensions()
    }
}
<|endoftext|>


<commit_before>extern crate libc;
extern crate libtensorflow_sys;

use std::ffi::CStr;
use std::fmt;
use std::fmt::Display;
use std::fmt::Formatter;
use std::ops::Drop;

use libtensorflow_sys as tf;

////////////////////////

fn check_not_null<T>(p: *mut T) -> *mut T {
  assert!(!p.is_null());
  p
}

////////////////////////

macro_rules! impl_new {
  ($name: ident, $call:ident) => {
    impl $name {
      pub fn new() -> Self {
        unsafe {
          $name {
            inner: check_not_null(tf::$call()),
          }
        }
      }
    }
  }
}

////////////////////////

macro_rules! impl_drop {
  ($name: ident, $call:ident) => {
    impl Drop for $name {
      fn drop(&mut self) {
        unsafe {
          tf::$call(self.inner);
        }
      }
    }
  }
}

////////////////////////

macro_rules! c_enum {
  ($enum_name:ident { $($name:ident = $num:expr),* }) => {
    #[derive(PartialEq,Eq,PartialOrd,Ord,Debug)]
    pub enum $enum_name {
      UnrecognizedEnumValue(::libc::c_uint),
      $($name),*
    }

    impl $enum_name {
      #[allow(dead_code)]
      fn from_int(value: ::libc::c_uint) -> $enum_name {
        match value {
          $($num => $enum_name::$name,)*
          c => $enum_name::UnrecognizedEnumValue(c),
        }
      }

      #[allow(dead_code)]
      fn to_int(&self) -> ::libc::c_uint {
        match self {
          &$enum_name::UnrecognizedEnumValue(c) => c,
          $(&$enum_name::$name => $num),*
        }
      }
    }

    impl ::std::fmt::Display for $enum_name {
      fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        match self {
          $(&$enum_name::$name => f.write_str(stringify!($name)),)*
          &$enum_name::UnrecognizedEnumValue(c) => write!(f, "UnrecognizedEnumValue({})", c),
        }
      }
    }
  };
  ($enum_name:ident { $($name:ident = $num:expr,)* }) => {
    c_enum!($enum_name { $($name = $num),* });
  }
}

////////////////////////

c_enum!(Code {
  Ok = 0,
  Cancelled = 1,
  Unknown = 2,
  InvalidArgument = 3,
  DeadlineExceeded = 4,
  NotFound = 5,
  AlreadyExists = 6,
  PermissionDenied = 7,
  ResourceExhausted = 8,
  FailedPrecondition = 9,
  Aborted = 10,
  OutOfRange = 11,
  Unimplemented = 12,
  Internal = 13,
  Unavailable = 14,
  DataLoss = 15,
  Unauthenticated = 16,
});

////////////////////////

c_enum!(DataType {
  Float = 1,
  Double = 2,
  Int32 = 3,
  UInt8 = 4,
  Int16 = 5,
  Int8 = 6,
  String = 7,
  Complex = 8,
  Int64 = 9,
  Bool = 10,
  QInt8 = 11,
  QUInt8 = 12,
  QInt32 = 13,
  BFloat16 = 14,
  QInt16 = 15,
  QUInt16 = 16,
});

////////////////////////

pub struct Status {
  inner: *mut tf::TF_Status,
}

impl_new!(Status, TF_NewStatus);
impl_drop!(Status, TF_DeleteStatus);

impl Status {
  pub fn code(&self) -> Code {
    unsafe {
      Code::from_int(tf::TF_GetCode(self.inner))
    }
  }

  pub fn is_ok(&self) -> bool {
    self.code() == Code::Ok
  }
}

impl Display for Status {
  fn fmt(&self, f: &mut Formatter) -> fmt::Result {
    unsafe {
      try!(write!(f, "{}: ", self.code()));
      let msg = match CStr::from_ptr(tf::TF_Message(self.inner)).to_str() {
        Ok(s) => s,
        Err(_) => "<invalid UTF-8 in message>",
      };
      f.write_str(msg)
    }
  }
}

////////////////////////

pub struct SessionOptions {
  inner: *mut tf::TF_SessionOptions,
}

impl_new!(SessionOptions, TF_NewSessionOptions);
impl_drop!(SessionOptions, TF_DeleteSessionOptions);

////////////////////////

pub struct Session {
  inner: *mut tf::TF_Session,
}

impl Session {
  pub fn new(options: &SessionOptions) -> (Option<Self>, Status) {
    let status = Status::new();
    let inner = unsafe { tf::TF_NewSession(options.inner, status.inner) };
    let session = if inner.is_null() {
      None
    } else {
      Some(Session {
        inner: inner,
      })
    };
    (session, status)
  }

  pub fn close(&mut self) -> Status {
    let status = Status::new();
    unsafe {
      tf::TF_CloseSession(self.inner, status.inner);
    }
    status
  }
}

impl Drop for Session {
  fn drop(&mut self) {
    let status = Status::new();
    unsafe {
      tf::TF_DeleteSession(self.inner, status.inner);
    }
    // TODO: What do we do with the status?
  }
}

////////////////////////

#[cfg(test)]
mod tests {
  use super::*;

  fn create_session() -> Session {
    let options = SessionOptions::new();
    match Session::new(&options) {
      (Some(session), status) => {
        assert_eq!(status.code(), Code::Ok);
        session
      },
      (None, status) => panic!("Creating session failed with status: {}", status),
    }
  }

  #[test]
  fn smoke() {
    create_session();
  }

  #[test]
  fn test_close() {
    let status = create_session().close();
    assert!(status.is_ok());
  }
}
<commit_msg>Change result type of Session::new<commit_after>extern crate libc;
extern crate libtensorflow_sys;

use std::ffi::CStr;
use std::fmt;
use std::fmt::Display;
use std::fmt::Formatter;
use std::ops::Drop;

use libtensorflow_sys as tf;

////////////////////////

fn check_not_null<T>(p: *mut T) -> *mut T {
  assert!(!p.is_null());
  p
}

////////////////////////

macro_rules! impl_new {
  ($name: ident, $call:ident) => {
    impl $name {
      pub fn new() -> Self {
        unsafe {
          $name {
            inner: check_not_null(tf::$call()),
          }
        }
      }
    }
  }
}

////////////////////////

macro_rules! impl_drop {
  ($name: ident, $call:ident) => {
    impl Drop for $name {
      fn drop(&mut self) {
        unsafe {
          tf::$call(self.inner);
        }
      }
    }
  }
}

////////////////////////

macro_rules! c_enum {
  ($enum_name:ident { $($name:ident = $num:expr),* }) => {
    #[derive(PartialEq,Eq,PartialOrd,Ord,Debug)]
    pub enum $enum_name {
      UnrecognizedEnumValue(::libc::c_uint),
      $($name),*
    }

    impl $enum_name {
      #[allow(dead_code)]
      fn from_int(value: ::libc::c_uint) -> $enum_name {
        match value {
          $($num => $enum_name::$name,)*
          c => $enum_name::UnrecognizedEnumValue(c),
        }
      }

      #[allow(dead_code)]
      fn to_int(&self) -> ::libc::c_uint {
        match self {
          &$enum_name::UnrecognizedEnumValue(c) => c,
          $(&$enum_name::$name => $num),*
        }
      }
    }

    impl ::std::fmt::Display for $enum_name {
      fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        match self {
          $(&$enum_name::$name => f.write_str(stringify!($name)),)*
          &$enum_name::UnrecognizedEnumValue(c) => write!(f, "UnrecognizedEnumValue({})", c),
        }
      }
    }
  };
  ($enum_name:ident { $($name:ident = $num:expr,)* }) => {
    c_enum!($enum_name { $($name = $num),* });
  }
}

////////////////////////

c_enum!(Code {
  Ok = 0,
  Cancelled = 1,
  Unknown = 2,
  InvalidArgument = 3,
  DeadlineExceeded = 4,
  NotFound = 5,
  AlreadyExists = 6,
  PermissionDenied = 7,
  ResourceExhausted = 8,
  FailedPrecondition = 9,
  Aborted = 10,
  OutOfRange = 11,
  Unimplemented = 12,
  Internal = 13,
  Unavailable = 14,
  DataLoss = 15,
  Unauthenticated = 16,
});

////////////////////////

c_enum!(DataType {
  Float = 1,
  Double = 2,
  Int32 = 3,
  UInt8 = 4,
  Int16 = 5,
  Int8 = 6,
  String = 7,
  Complex = 8,
  Int64 = 9,
  Bool = 10,
  QInt8 = 11,
  QUInt8 = 12,
  QInt32 = 13,
  BFloat16 = 14,
  QInt16 = 15,
  QUInt16 = 16,
});

////////////////////////

pub struct Status {
  inner: *mut tf::TF_Status,
}

impl_new!(Status, TF_NewStatus);
impl_drop!(Status, TF_DeleteStatus);

impl Status {
  pub fn code(&self) -> Code {
    unsafe {
      Code::from_int(tf::TF_GetCode(self.inner))
    }
  }

  pub fn is_ok(&self) -> bool {
    self.code() == Code::Ok
  }
}

impl Display for Status {
  fn fmt(&self, f: &mut Formatter) -> fmt::Result {
    unsafe {
      try!(write!(f, "{}: ", self.code()));
      let msg = match CStr::from_ptr(tf::TF_Message(self.inner)).to_str() {
        Ok(s) => s,
        Err(_) => "<invalid UTF-8 in message>",
      };
      f.write_str(msg)
    }
  }
}

////////////////////////

pub struct SessionOptions {
  inner: *mut tf::TF_SessionOptions,
}

impl_new!(SessionOptions, TF_NewSessionOptions);
impl_drop!(SessionOptions, TF_DeleteSessionOptions);

////////////////////////

pub struct Session {
  inner: *mut tf::TF_Session,
}

impl Session {
  pub fn new(options: &SessionOptions) -> Result<Self> {
    let status = Status::new();
    let inner = unsafe { tf::TF_NewSession(options.inner, status.inner) };
    if inner.is_null() {
      Err(status)
    } else {
      Ok(Session {
        inner: inner,
      })
    }
  }

  pub fn close(&mut self) -> Status {
    let status = Status::new();
    unsafe {
      tf::TF_CloseSession(self.inner, status.inner);
    }
    status
  }
}

impl Drop for Session {
  fn drop(&mut self) {
    let status = Status::new();
    unsafe {
      tf::TF_DeleteSession(self.inner, status.inner);
    }
    // TODO: What do we do with the status?
  }
}

////////////////////////

pub type Result<T> = std::result::Result<T, Status>;

////////////////////////

#[cfg(test)]
mod tests {
  use super::*;

  fn create_session() -> Session {
    let options = SessionOptions::new();
    match Session::new(&options) {
      Ok(session) => session,
      Err(status) => panic!("Creating session failed with status: {}", status),
    }
  }

  #[test]
  fn smoke() {
    create_session();
  }

  #[test]
  fn test_close() {
    let status = create_session().close();
    assert!(status.is_ok());
  }
}
<|endoftext|>