AzureMarker
3 years ago
358 changed files with 0 additions and 103830 deletions
@ -1,12 +0,0 @@ |
|||||||
[package] |
|
||||||
name = "std" |
|
||||||
version = "0.0.0" |
|
||||||
license = "MIT/Apache 2.0" |
|
||||||
|
|
||||||
[dependencies.alloc_system] |
|
||||||
git = "https://github.com/rust3ds/alloc_system3ds" |
|
||||||
|
|
||||||
[dependencies.ctru-sys] |
|
||||||
path = "../ctru-sys" |
|
||||||
default-features = false |
|
||||||
features = ["stdbuild"] |
|
@ -1,69 +0,0 @@ |
|||||||
A work-in-progress port of the Rust Standard Library for the Nintendo 3DS, based on [ctrulib](https://github.com/smealum/ctrulib/) and the [devkitARM](http://devkitPro.org) toolchain. |
|
||||||
|
|
||||||
## Structure |
|
||||||
|
|
||||||
This library aims to mimick the Rust standard library's public interface as closely as possible, exposing functionality that is common between the 3DS and other platforms. System-specific functionality such as control input, save file management, GPU features, and so forth are implemented in `ctru-rs`. |
|
||||||
|
|
||||||
## Working modules |
|
||||||
|
|
||||||
* `any` |
|
||||||
* `ascii` |
|
||||||
* `borrow` |
|
||||||
* `boxed` |
|
||||||
* `cell` |
|
||||||
* `char` |
|
||||||
* `clone` |
|
||||||
* `cmp` |
|
||||||
* `collections` |
|
||||||
* `convert` |
|
||||||
* `default` |
|
||||||
* `error` |
|
||||||
* `f32` |
|
||||||
* `f64` |
|
||||||
* `ffi` |
|
||||||
* `fmt` |
|
||||||
* `fs` Both `sdmc:/` and `romfs:/` paths are supported in standard file operations |
|
||||||
* `hash` |
|
||||||
* `i8` |
|
||||||
* `i16` |
|
||||||
* `i32` |
|
||||||
* `i64` |
|
||||||
* `io` |
|
||||||
* `isize` |
|
||||||
* `iter` |
|
||||||
* `marker` |
|
||||||
* `mem` |
|
||||||
* `num` |
|
||||||
* `ops` |
|
||||||
* `option` |
|
||||||
* `panic` |
|
||||||
* `path` |
|
||||||
* `prelude` |
|
||||||
* `ptr` |
|
||||||
* `rc` |
|
||||||
* `result` |
|
||||||
* `slice` |
|
||||||
* `str` |
|
||||||
* `string` |
|
||||||
* `sync` |
|
||||||
* `time` |
|
||||||
* `thread` Threads are able to be spawned, but without the ability to pin to a specific core or set thread priority |
|
||||||
* `u8` |
|
||||||
* `u16` |
|
||||||
* `u32` |
|
||||||
* `u64` |
|
||||||
* `usize` |
|
||||||
* `vec` |
|
||||||
* `heap` |
|
||||||
* `i128` |
|
||||||
* `intrinsics` |
|
||||||
* `raw` |
|
||||||
* `u128` |
|
||||||
|
|
||||||
# Partially working modules |
|
||||||
* `net` Anything not involving IPv6 should work after initializing the `Soc` service in `ctru-rs` |
|
||||||
* `os` The modules in here should work, but they aren't well-tested |
|
||||||
|
|
||||||
# Non-working modules |
|
||||||
* `env` argc/argv can be implemented but have not been yet |
|
||||||
* `process` Unable to be implemented due to platform incompatibilities |
|
@ -1,184 +0,0 @@ |
|||||||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Memory allocation APIs
|
|
||||||
//!
|
|
||||||
//! In a given program, the standard library has one “global” memory allocator
|
|
||||||
//! that is used for example by `Box<T>` and `Vec<T>`.
|
|
||||||
//!
|
|
||||||
//! Currently the default global allocator is unspecified.
|
|
||||||
//! The compiler may link to a version of [jemalloc] on some platforms,
|
|
||||||
//! but this is not guaranteed.
|
|
||||||
//! Libraries, however, like `cdylib`s and `staticlib`s are guaranteed
|
|
||||||
//! to use the [`System`] by default.
|
|
||||||
//!
|
|
||||||
//! [jemalloc]: https://github.com/jemalloc/jemalloc
|
|
||||||
//! [`System`]: struct.System.html
|
|
||||||
//!
|
|
||||||
//! # The `#[global_allocator]` attribute
|
|
||||||
//!
|
|
||||||
//! This attribute allows configuring the choice of global allocator.
|
|
||||||
//! You can use this to implement a completely custom global allocator
|
|
||||||
//! to route all default allocation requests to a custom object.
|
|
||||||
//!
|
|
||||||
//! ```rust
|
|
||||||
//! use std::alloc::{GlobalAlloc, System, Layout};
|
|
||||||
//!
|
|
||||||
//! struct MyAllocator;
|
|
||||||
//!
|
|
||||||
//! unsafe impl GlobalAlloc for MyAllocator {
|
|
||||||
//! unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
|
||||||
//! System.alloc(layout)
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
|
|
||||||
//! System.dealloc(ptr, layout)
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! #[global_allocator]
|
|
||||||
//! static GLOBAL: MyAllocator = MyAllocator;
|
|
||||||
//!
|
|
||||||
//! fn main() {
|
|
||||||
//! // This `Vec` will allocate memory through `GLOBAL` above
|
|
||||||
//! let mut v = Vec::new();
|
|
||||||
//! v.push(1);
|
|
||||||
//! }
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! The attribute is used on a `static` item whose type implements the
|
|
||||||
//! [`GlobalAlloc`] trait. This type can be provided by an external library:
|
|
||||||
//!
|
|
||||||
//! [`GlobalAlloc`]: ../../core/alloc/trait.GlobalAlloc.html
|
|
||||||
//!
|
|
||||||
//! ```rust,ignore (demonstrates crates.io usage)
|
|
||||||
//! extern crate jemallocator;
|
|
||||||
//!
|
|
||||||
//! use jemallocator::Jemalloc;
|
|
||||||
//!
|
|
||||||
//! #[global_allocator]
|
|
||||||
//! static GLOBAL: Jemalloc = Jemalloc;
|
|
||||||
//!
|
|
||||||
//! fn main() {}
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! The `#[global_allocator]` can only be used once in a crate
|
|
||||||
//! or its recursive dependencies.
|
|
||||||
|
|
||||||
#![stable(feature = "alloc_module", since = "1.28.0")] |
|
||||||
|
|
||||||
use core::sync::atomic::{AtomicPtr, Ordering}; |
|
||||||
use core::{mem, ptr}; |
|
||||||
use sys_common::util::dumb_print; |
|
||||||
|
|
||||||
#[stable(feature = "alloc_module", since = "1.28.0")] |
|
||||||
#[doc(inline)] |
|
||||||
pub use alloc_crate::alloc::*; |
|
||||||
|
|
||||||
#[stable(feature = "alloc_system_type", since = "1.28.0")] |
|
||||||
#[doc(inline)] |
|
||||||
pub use alloc_system::System; |
|
||||||
|
|
||||||
static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut()); |
|
||||||
|
|
||||||
/// Registers a custom allocation error hook, replacing any that was previously registered.
|
|
||||||
///
|
|
||||||
/// The allocation error hook is invoked when an infallible memory allocation fails, before
|
|
||||||
/// the runtime aborts. The default hook prints a message to standard error,
|
|
||||||
/// but this behavior can be customized with the [`set_alloc_error_hook`] and
|
|
||||||
/// [`take_alloc_error_hook`] functions.
|
|
||||||
///
|
|
||||||
/// The hook is provided with a `Layout` struct which contains information
|
|
||||||
/// about the allocation that failed.
|
|
||||||
///
|
|
||||||
/// The allocation error hook is a global resource.
|
|
||||||
#[unstable(feature = "alloc_error_hook", issue = "51245")] |
|
||||||
pub fn set_alloc_error_hook(hook: fn(Layout)) { |
|
||||||
HOOK.store(hook as *mut (), Ordering::SeqCst); |
|
||||||
} |
|
||||||
|
|
||||||
/// Unregisters the current allocation error hook, returning it.
|
|
||||||
///
|
|
||||||
/// *See also the function [`set_alloc_error_hook`].*
|
|
||||||
///
|
|
||||||
/// If no custom hook is registered, the default hook will be returned.
|
|
||||||
#[unstable(feature = "alloc_error_hook", issue = "51245")] |
|
||||||
pub fn take_alloc_error_hook() -> fn(Layout) { |
|
||||||
let hook = HOOK.swap(ptr::null_mut(), Ordering::SeqCst); |
|
||||||
if hook.is_null() { |
|
||||||
default_alloc_error_hook |
|
||||||
} else { |
|
||||||
unsafe { mem::transmute(hook) } |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fn default_alloc_error_hook(layout: Layout) { |
|
||||||
dumb_print(format_args!("memory allocation of {} bytes failed", layout.size())); |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(not(test))] |
|
||||||
#[doc(hidden)] |
|
||||||
#[alloc_error_handler] |
|
||||||
#[unstable(feature = "alloc_internals", issue = "0")] |
|
||||||
pub fn rust_oom(layout: Layout) -> ! { |
|
||||||
let hook = HOOK.load(Ordering::SeqCst); |
|
||||||
let hook: fn(Layout) = if hook.is_null() { |
|
||||||
default_alloc_error_hook |
|
||||||
} else { |
|
||||||
unsafe { mem::transmute(hook) } |
|
||||||
}; |
|
||||||
hook(layout); |
|
||||||
unsafe { ::sys::abort_internal(); } |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(not(test))] |
|
||||||
#[doc(hidden)] |
|
||||||
#[allow(unused_attributes)] |
|
||||||
#[unstable(feature = "alloc_internals", issue = "0")] |
|
||||||
pub mod __default_lib_allocator { |
|
||||||
use super::{System, Layout, GlobalAlloc}; |
|
||||||
// for symbol names src/librustc/middle/allocator.rs
|
|
||||||
// for signatures src/librustc_allocator/lib.rs
|
|
||||||
|
|
||||||
// linkage directives are provided as part of the current compiler allocator
|
|
||||||
// ABI
|
|
||||||
|
|
||||||
#[no_mangle] |
|
||||||
#[rustc_std_internal_symbol] |
|
||||||
pub unsafe extern fn __rdl_alloc(size: usize, align: usize) -> *mut u8 { |
|
||||||
let layout = Layout::from_size_align_unchecked(size, align); |
|
||||||
System.alloc(layout) |
|
||||||
} |
|
||||||
|
|
||||||
#[no_mangle] |
|
||||||
#[rustc_std_internal_symbol] |
|
||||||
pub unsafe extern fn __rdl_dealloc(ptr: *mut u8, |
|
||||||
size: usize, |
|
||||||
align: usize) { |
|
||||||
System.dealloc(ptr, Layout::from_size_align_unchecked(size, align)) |
|
||||||
} |
|
||||||
|
|
||||||
#[no_mangle] |
|
||||||
#[rustc_std_internal_symbol] |
|
||||||
pub unsafe extern fn __rdl_realloc(ptr: *mut u8, |
|
||||||
old_size: usize, |
|
||||||
align: usize, |
|
||||||
new_size: usize) -> *mut u8 { |
|
||||||
let old_layout = Layout::from_size_align_unchecked(old_size, align); |
|
||||||
System.realloc(ptr, old_layout, new_size) |
|
||||||
} |
|
||||||
|
|
||||||
#[no_mangle] |
|
||||||
#[rustc_std_internal_symbol] |
|
||||||
pub unsafe extern fn __rdl_alloc_zeroed(size: usize, align: usize) -> *mut u8 { |
|
||||||
let layout = Layout::from_size_align_unchecked(size, align); |
|
||||||
System.alloc_zeroed(layout) |
|
||||||
} |
|
||||||
} |
|
@ -1,134 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#![deny(warnings)] |
|
||||||
|
|
||||||
extern crate build_helper; |
|
||||||
extern crate cc; |
|
||||||
|
|
||||||
use build_helper::native_lib_boilerplate; |
|
||||||
use std::env; |
|
||||||
use std::fs::File; |
|
||||||
|
|
||||||
fn main() { |
|
||||||
let target = env::var("TARGET").expect("TARGET was not set"); |
|
||||||
if cfg!(feature = "backtrace") && |
|
||||||
!target.contains("cloudabi") && |
|
||||||
!target.contains("emscripten") && |
|
||||||
!target.contains("msvc") && |
|
||||||
!target.contains("wasm32") |
|
||||||
{ |
|
||||||
let _ = build_libbacktrace(&target); |
|
||||||
} |
|
||||||
|
|
||||||
if target.contains("linux") { |
|
||||||
if target.contains("android") { |
|
||||||
println!("cargo:rustc-link-lib=dl"); |
|
||||||
println!("cargo:rustc-link-lib=log"); |
|
||||||
println!("cargo:rustc-link-lib=gcc"); |
|
||||||
} else if !target.contains("musl") { |
|
||||||
println!("cargo:rustc-link-lib=dl"); |
|
||||||
println!("cargo:rustc-link-lib=rt"); |
|
||||||
println!("cargo:rustc-link-lib=pthread"); |
|
||||||
} |
|
||||||
} else if target.contains("freebsd") { |
|
||||||
println!("cargo:rustc-link-lib=execinfo"); |
|
||||||
println!("cargo:rustc-link-lib=pthread"); |
|
||||||
} else if target.contains("dragonfly") || target.contains("bitrig") || |
|
||||||
target.contains("netbsd") || target.contains("openbsd") { |
|
||||||
println!("cargo:rustc-link-lib=pthread"); |
|
||||||
} else if target.contains("solaris") { |
|
||||||
println!("cargo:rustc-link-lib=socket"); |
|
||||||
println!("cargo:rustc-link-lib=posix4"); |
|
||||||
println!("cargo:rustc-link-lib=pthread"); |
|
||||||
println!("cargo:rustc-link-lib=resolv"); |
|
||||||
} else if target.contains("apple-darwin") { |
|
||||||
println!("cargo:rustc-link-lib=System"); |
|
||||||
|
|
||||||
// res_init and friends require -lresolv on macOS/iOS.
|
|
||||||
// See #41582 and http://blog.achernya.com/2013/03/os-x-has-silly-libsystem.html
|
|
||||||
println!("cargo:rustc-link-lib=resolv"); |
|
||||||
} else if target.contains("apple-ios") { |
|
||||||
println!("cargo:rustc-link-lib=System"); |
|
||||||
println!("cargo:rustc-link-lib=objc"); |
|
||||||
println!("cargo:rustc-link-lib=framework=Security"); |
|
||||||
println!("cargo:rustc-link-lib=framework=Foundation"); |
|
||||||
println!("cargo:rustc-link-lib=resolv"); |
|
||||||
} else if target.contains("windows") { |
|
||||||
println!("cargo:rustc-link-lib=advapi32"); |
|
||||||
println!("cargo:rustc-link-lib=ws2_32"); |
|
||||||
println!("cargo:rustc-link-lib=userenv"); |
|
||||||
println!("cargo:rustc-link-lib=shell32"); |
|
||||||
} else if target.contains("fuchsia") { |
|
||||||
println!("cargo:rustc-link-lib=zircon"); |
|
||||||
println!("cargo:rustc-link-lib=fdio"); |
|
||||||
} else if target.contains("cloudabi") { |
|
||||||
if cfg!(feature = "backtrace") { |
|
||||||
println!("cargo:rustc-link-lib=unwind"); |
|
||||||
} |
|
||||||
println!("cargo:rustc-link-lib=c"); |
|
||||||
println!("cargo:rustc-link-lib=compiler_rt"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fn build_libbacktrace(target: &str) -> Result<(), ()> { |
|
||||||
let native = native_lib_boilerplate("libbacktrace", "libbacktrace", "backtrace", "")?; |
|
||||||
|
|
||||||
let mut build = cc::Build::new(); |
|
||||||
build |
|
||||||
.flag("-fvisibility=hidden") |
|
||||||
.include("../libbacktrace") |
|
||||||
.include(&native.out_dir) |
|
||||||
.out_dir(&native.out_dir) |
|
||||||
.warnings(false) |
|
||||||
.file("../libbacktrace/alloc.c") |
|
||||||
.file("../libbacktrace/backtrace.c") |
|
||||||
.file("../libbacktrace/dwarf.c") |
|
||||||
.file("../libbacktrace/fileline.c") |
|
||||||
.file("../libbacktrace/posix.c") |
|
||||||
.file("../libbacktrace/read.c") |
|
||||||
.file("../libbacktrace/sort.c") |
|
||||||
.file("../libbacktrace/state.c"); |
|
||||||
|
|
||||||
if target.contains("darwin") { |
|
||||||
build.file("../libbacktrace/macho.c"); |
|
||||||
} else if target.contains("windows") { |
|
||||||
build.file("../libbacktrace/pecoff.c"); |
|
||||||
} else { |
|
||||||
build.file("../libbacktrace/elf.c"); |
|
||||||
|
|
||||||
let pointer_width = env::var("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap(); |
|
||||||
if pointer_width == "64" { |
|
||||||
build.define("BACKTRACE_ELF_SIZE", "64"); |
|
||||||
} else { |
|
||||||
build.define("BACKTRACE_ELF_SIZE", "32"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
File::create(native.out_dir.join("backtrace-supported.h")).unwrap(); |
|
||||||
build.define("BACKTRACE_SUPPORTED", "1"); |
|
||||||
build.define("BACKTRACE_USES_MALLOC", "1"); |
|
||||||
build.define("BACKTRACE_SUPPORTS_THREADS", "0"); |
|
||||||
build.define("BACKTRACE_SUPPORTS_DATA", "0"); |
|
||||||
|
|
||||||
File::create(native.out_dir.join("config.h")).unwrap(); |
|
||||||
if !target.contains("apple-ios") && |
|
||||||
!target.contains("solaris") && |
|
||||||
!target.contains("redox") && |
|
||||||
!target.contains("android") && |
|
||||||
!target.contains("haiku") { |
|
||||||
build.define("HAVE_DL_ITERATE_PHDR", "1"); |
|
||||||
} |
|
||||||
build.define("_GNU_SOURCE", "1"); |
|
||||||
build.define("_LARGE_FILES", "1"); |
|
||||||
|
|
||||||
build.compile("backtrace"); |
|
||||||
Ok(()) |
|
||||||
} |
|
@ -1,128 +0,0 @@ |
|||||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#![cfg(test)] |
|
||||||
|
|
||||||
extern crate test; |
|
||||||
|
|
||||||
use self::test::Bencher; |
|
||||||
|
|
||||||
#[bench] |
|
||||||
fn new_drop(b: &mut Bencher) { |
|
||||||
use super::map::HashMap; |
|
||||||
|
|
||||||
b.iter(|| { |
|
||||||
let m: HashMap<i32, i32> = HashMap::new(); |
|
||||||
assert_eq!(m.len(), 0); |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
#[bench] |
|
||||||
fn new_insert_drop(b: &mut Bencher) { |
|
||||||
use super::map::HashMap; |
|
||||||
|
|
||||||
b.iter(|| { |
|
||||||
let mut m = HashMap::new(); |
|
||||||
m.insert(0, 0); |
|
||||||
assert_eq!(m.len(), 1); |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
#[bench] |
|
||||||
fn grow_by_insertion(b: &mut Bencher) { |
|
||||||
use super::map::HashMap; |
|
||||||
|
|
||||||
let mut m = HashMap::new(); |
|
||||||
|
|
||||||
for i in 1..1001 { |
|
||||||
m.insert(i, i); |
|
||||||
} |
|
||||||
|
|
||||||
let mut k = 1001; |
|
||||||
|
|
||||||
b.iter(|| { |
|
||||||
m.insert(k, k); |
|
||||||
k += 1; |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
#[bench] |
|
||||||
fn find_existing(b: &mut Bencher) { |
|
||||||
use super::map::HashMap; |
|
||||||
|
|
||||||
let mut m = HashMap::new(); |
|
||||||
|
|
||||||
for i in 1..1001 { |
|
||||||
m.insert(i, i); |
|
||||||
} |
|
||||||
|
|
||||||
b.iter(|| { |
|
||||||
for i in 1..1001 { |
|
||||||
m.contains_key(&i); |
|
||||||
} |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
#[bench] |
|
||||||
fn find_nonexisting(b: &mut Bencher) { |
|
||||||
use super::map::HashMap; |
|
||||||
|
|
||||||
let mut m = HashMap::new(); |
|
||||||
|
|
||||||
for i in 1..1001 { |
|
||||||
m.insert(i, i); |
|
||||||
} |
|
||||||
|
|
||||||
b.iter(|| { |
|
||||||
for i in 1001..2001 { |
|
||||||
m.contains_key(&i); |
|
||||||
} |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
#[bench] |
|
||||||
fn hashmap_as_queue(b: &mut Bencher) { |
|
||||||
use super::map::HashMap; |
|
||||||
|
|
||||||
let mut m = HashMap::new(); |
|
||||||
|
|
||||||
for i in 1..1001 { |
|
||||||
m.insert(i, i); |
|
||||||
} |
|
||||||
|
|
||||||
let mut k = 1; |
|
||||||
|
|
||||||
b.iter(|| { |
|
||||||
m.remove(&k); |
|
||||||
m.insert(k + 1000, k + 1000); |
|
||||||
k += 1; |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
#[bench] |
|
||||||
fn get_remove_insert(b: &mut Bencher) { |
|
||||||
use super::map::HashMap; |
|
||||||
|
|
||||||
let mut m = HashMap::new(); |
|
||||||
|
|
||||||
for i in 1..1001 { |
|
||||||
m.insert(i, i); |
|
||||||
} |
|
||||||
|
|
||||||
let mut k = 1; |
|
||||||
|
|
||||||
b.iter(|| { |
|
||||||
m.get(&(k + 400)); |
|
||||||
m.get(&(k + 2000)); |
|
||||||
m.remove(&k); |
|
||||||
m.insert(k + 1000, k + 1000); |
|
||||||
k += 1; |
|
||||||
}) |
|
||||||
} |
|
File diff suppressed because it is too large
Load Diff
@ -1,24 +0,0 @@ |
|||||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Unordered containers, implemented as hash-tables
|
|
||||||
|
|
||||||
mod bench; |
|
||||||
mod table; |
|
||||||
pub mod map; |
|
||||||
pub mod set; |
|
||||||
|
|
||||||
trait Recover<Q: ?Sized> { |
|
||||||
type Key; |
|
||||||
|
|
||||||
fn get(&self, key: &Q) -> Option<&Self::Key>; |
|
||||||
fn take(&mut self, key: &Q) -> Option<Self::Key>; |
|
||||||
fn replace(&mut self, key: Self::Key) -> Option<Self::Key>; |
|
||||||
} |
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,457 +0,0 @@ |
|||||||
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Collection types.
|
|
||||||
//!
|
|
||||||
//! Rust's standard collection library provides efficient implementations of the
|
|
||||||
//! most common general purpose programming data structures. By using the
|
|
||||||
//! standard implementations, it should be possible for two libraries to
|
|
||||||
//! communicate without significant data conversion.
|
|
||||||
//!
|
|
||||||
//! To get this out of the way: you should probably just use [`Vec`] or [`HashMap`].
|
|
||||||
//! These two collections cover most use cases for generic data storage and
|
|
||||||
//! processing. They are exceptionally good at doing what they do. All the other
|
|
||||||
//! collections in the standard library have specific use cases where they are
|
|
||||||
//! the optimal choice, but these cases are borderline *niche* in comparison.
|
|
||||||
//! Even when `Vec` and `HashMap` are technically suboptimal, they're probably a
|
|
||||||
//! good enough choice to get started.
|
|
||||||
//!
|
|
||||||
//! Rust's collections can be grouped into four major categories:
|
|
||||||
//!
|
|
||||||
//! * Sequences: [`Vec`], [`VecDeque`], [`LinkedList`]
|
|
||||||
//! * Maps: [`HashMap`], [`BTreeMap`]
|
|
||||||
//! * Sets: [`HashSet`], [`BTreeSet`]
|
|
||||||
//! * Misc: [`BinaryHeap`]
|
|
||||||
//!
|
|
||||||
//! # When Should You Use Which Collection?
|
|
||||||
//!
|
|
||||||
//! These are fairly high-level and quick break-downs of when each collection
|
|
||||||
//! should be considered. Detailed discussions of strengths and weaknesses of
|
|
||||||
//! individual collections can be found on their own documentation pages.
|
|
||||||
//!
|
|
||||||
//! ### Use a `Vec` when:
|
|
||||||
//! * You want to collect items up to be processed or sent elsewhere later, and
|
|
||||||
//! don't care about any properties of the actual values being stored.
|
|
||||||
//! * You want a sequence of elements in a particular order, and will only be
|
|
||||||
//! appending to (or near) the end.
|
|
||||||
//! * You want a stack.
|
|
||||||
//! * You want a resizable array.
|
|
||||||
//! * You want a heap-allocated array.
|
|
||||||
//!
|
|
||||||
//! ### Use a `VecDeque` when:
|
|
||||||
//! * You want a [`Vec`] that supports efficient insertion at both ends of the
|
|
||||||
//! sequence.
|
|
||||||
//! * You want a queue.
|
|
||||||
//! * You want a double-ended queue (deque).
|
|
||||||
//!
|
|
||||||
//! ### Use a `LinkedList` when:
|
|
||||||
//! * You want a [`Vec`] or [`VecDeque`] of unknown size, and can't tolerate
|
|
||||||
//! amortization.
|
|
||||||
//! * You want to efficiently split and append lists.
|
|
||||||
//! * You are *absolutely* certain you *really*, *truly*, want a doubly linked
|
|
||||||
//! list.
|
|
||||||
//!
|
|
||||||
//! ### Use a `HashMap` when:
|
|
||||||
//! * You want to associate arbitrary keys with an arbitrary value.
|
|
||||||
//! * You want a cache.
|
|
||||||
//! * You want a map, with no extra functionality.
|
|
||||||
//!
|
|
||||||
//! ### Use a `BTreeMap` when:
|
|
||||||
//! * You want a map sorted by its keys.
|
|
||||||
//! * You want to be able to get a range of entries on-demand.
|
|
||||||
//! * You're interested in what the smallest or largest key-value pair is.
|
|
||||||
//! * You want to find the largest or smallest key that is smaller or larger
|
|
||||||
//! than something.
|
|
||||||
//!
|
|
||||||
//! ### Use the `Set` variant of any of these `Map`s when:
|
|
||||||
//! * You just want to remember which keys you've seen.
|
|
||||||
//! * There is no meaningful value to associate with your keys.
|
|
||||||
//! * You just want a set.
|
|
||||||
//!
|
|
||||||
//! ### Use a `BinaryHeap` when:
|
|
||||||
//!
|
|
||||||
//! * You want to store a bunch of elements, but only ever want to process the
|
|
||||||
//! "biggest" or "most important" one at any given time.
|
|
||||||
//! * You want a priority queue.
|
|
||||||
//!
|
|
||||||
//! # Performance
|
|
||||||
//!
|
|
||||||
//! Choosing the right collection for the job requires an understanding of what
|
|
||||||
//! each collection is good at. Here we briefly summarize the performance of
|
|
||||||
//! different collections for certain important operations. For further details,
|
|
||||||
//! see each type's documentation, and note that the names of actual methods may
|
|
||||||
//! differ from the tables below on certain collections.
|
|
||||||
//!
|
|
||||||
//! Throughout the documentation, we will follow a few conventions. For all
|
|
||||||
//! operations, the collection's size is denoted by n. If another collection is
|
|
||||||
//! involved in the operation, it contains m elements. Operations which have an
|
|
||||||
//! *amortized* cost are suffixed with a `*`. Operations with an *expected*
|
|
||||||
//! cost are suffixed with a `~`.
|
|
||||||
//!
|
|
||||||
//! All amortized costs are for the potential need to resize when capacity is
|
|
||||||
//! exhausted. If a resize occurs it will take O(n) time. Our collections never
|
|
||||||
//! automatically shrink, so removal operations aren't amortized. Over a
|
|
||||||
//! sufficiently large series of operations, the average cost per operation will
|
|
||||||
//! deterministically equal the given cost.
|
|
||||||
//!
|
|
||||||
//! Only [`HashMap`] has expected costs, due to the probabilistic nature of hashing.
|
|
||||||
//! It is theoretically possible, though very unlikely, for [`HashMap`] to
|
|
||||||
//! experience worse performance.
|
|
||||||
//!
|
|
||||||
//! ## Sequences
|
|
||||||
//!
|
|
||||||
//! | | get(i) | insert(i) | remove(i) | append | split_off(i) |
|
|
||||||
//! |----------------|----------------|-----------------|----------------|--------|----------------|
|
|
||||||
//! | [`Vec`] | O(1) | O(n-i)* | O(n-i) | O(m)* | O(n-i) |
|
|
||||||
//! | [`VecDeque`] | O(1) | O(min(i, n-i))* | O(min(i, n-i)) | O(m)* | O(min(i, n-i)) |
|
|
||||||
//! | [`LinkedList`] | O(min(i, n-i)) | O(min(i, n-i)) | O(min(i, n-i)) | O(1) | O(min(i, n-i)) |
|
|
||||||
//!
|
|
||||||
//! Note that where ties occur, [`Vec`] is generally going to be faster than [`VecDeque`], and
|
|
||||||
//! [`VecDeque`] is generally going to be faster than [`LinkedList`].
|
|
||||||
//!
|
|
||||||
//! ## Maps
|
|
||||||
//!
|
|
||||||
//! For Sets, all operations have the cost of the equivalent Map operation.
|
|
||||||
//!
|
|
||||||
//! | | get | insert | remove | predecessor | append |
|
|
||||||
//! |--------------|-----------|----------|----------|-------------|--------|
|
|
||||||
//! | [`HashMap`] | O(1)~ | O(1)~* | O(1)~ | N/A | N/A |
|
|
||||||
//! | [`BTreeMap`] | O(log n) | O(log n) | O(log n) | O(log n) | O(n+m) |
|
|
||||||
//!
|
|
||||||
//! # Correct and Efficient Usage of Collections
|
|
||||||
//!
|
|
||||||
//! Of course, knowing which collection is the right one for the job doesn't
|
|
||||||
//! instantly permit you to use it correctly. Here are some quick tips for
|
|
||||||
//! efficient and correct usage of the standard collections in general. If
|
|
||||||
//! you're interested in how to use a specific collection in particular, consult
|
|
||||||
//! its documentation for detailed discussion and code examples.
|
|
||||||
//!
|
|
||||||
//! ## Capacity Management
|
|
||||||
//!
|
|
||||||
//! Many collections provide several constructors and methods that refer to
|
|
||||||
//! "capacity". These collections are generally built on top of an array.
|
|
||||||
//! Optimally, this array would be exactly the right size to fit only the
|
|
||||||
//! elements stored in the collection, but for the collection to do this would
|
|
||||||
//! be very inefficient. If the backing array was exactly the right size at all
|
|
||||||
//! times, then every time an element is inserted, the collection would have to
|
|
||||||
//! grow the array to fit it. Due to the way memory is allocated and managed on
|
|
||||||
//! most computers, this would almost surely require allocating an entirely new
|
|
||||||
//! array and copying every single element from the old one into the new one.
|
|
||||||
//! Hopefully you can see that this wouldn't be very efficient to do on every
|
|
||||||
//! operation.
|
|
||||||
//!
|
|
||||||
//! Most collections therefore use an *amortized* allocation strategy. They
|
|
||||||
//! generally let themselves have a fair amount of unoccupied space so that they
|
|
||||||
//! only have to grow on occasion. When they do grow, they allocate a
|
|
||||||
//! substantially larger array to move the elements into so that it will take a
|
|
||||||
//! while for another grow to be required. While this strategy is great in
|
|
||||||
//! general, it would be even better if the collection *never* had to resize its
|
|
||||||
//! backing array. Unfortunately, the collection itself doesn't have enough
|
|
||||||
//! information to do this itself. Therefore, it is up to us programmers to give
|
|
||||||
//! it hints.
|
|
||||||
//!
|
|
||||||
//! Any `with_capacity` constructor will instruct the collection to allocate
|
|
||||||
//! enough space for the specified number of elements. Ideally this will be for
|
|
||||||
//! exactly that many elements, but some implementation details may prevent
|
|
||||||
//! this. [`Vec`] and [`VecDeque`] can be relied on to allocate exactly the
|
|
||||||
//! requested amount, though. Use `with_capacity` when you know exactly how many
|
|
||||||
//! elements will be inserted, or at least have a reasonable upper-bound on that
|
|
||||||
//! number.
|
|
||||||
//!
|
|
||||||
//! When anticipating a large influx of elements, the `reserve` family of
|
|
||||||
//! methods can be used to hint to the collection how much room it should make
|
|
||||||
//! for the coming items. As with `with_capacity`, the precise behavior of
|
|
||||||
//! these methods will be specific to the collection of interest.
|
|
||||||
//!
|
|
||||||
//! For optimal performance, collections will generally avoid shrinking
|
|
||||||
//! themselves. If you believe that a collection will not soon contain any more
|
|
||||||
//! elements, or just really need the memory, the `shrink_to_fit` method prompts
|
|
||||||
//! the collection to shrink the backing array to the minimum size capable of
|
|
||||||
//! holding its elements.
|
|
||||||
//!
|
|
||||||
//! Finally, if ever you're interested in what the actual capacity of the
|
|
||||||
//! collection is, most collections provide a `capacity` method to query this
|
|
||||||
//! information on demand. This can be useful for debugging purposes, or for
|
|
||||||
//! use with the `reserve` methods.
|
|
||||||
//!
|
|
||||||
//! ## Iterators
|
|
||||||
//!
|
|
||||||
//! Iterators are a powerful and robust mechanism used throughout Rust's
|
|
||||||
//! standard libraries. Iterators provide a sequence of values in a generic,
|
|
||||||
//! safe, efficient and convenient way. The contents of an iterator are usually
|
|
||||||
//! *lazily* evaluated, so that only the values that are actually needed are
|
|
||||||
//! ever actually produced, and no allocation need be done to temporarily store
|
|
||||||
//! them. Iterators are primarily consumed using a `for` loop, although many
|
|
||||||
//! functions also take iterators where a collection or sequence of values is
|
|
||||||
//! desired.
|
|
||||||
//!
|
|
||||||
//! All of the standard collections provide several iterators for performing
|
|
||||||
//! bulk manipulation of their contents. The three primary iterators almost
|
|
||||||
//! every collection should provide are `iter`, `iter_mut`, and `into_iter`.
|
|
||||||
//! Some of these are not provided on collections where it would be unsound or
|
|
||||||
//! unreasonable to provide them.
|
|
||||||
//!
|
|
||||||
//! `iter` provides an iterator of immutable references to all the contents of a
|
|
||||||
//! collection in the most "natural" order. For sequence collections like [`Vec`],
|
|
||||||
//! this means the items will be yielded in increasing order of index starting
|
|
||||||
//! at 0. For ordered collections like [`BTreeMap`], this means that the items
|
|
||||||
//! will be yielded in sorted order. For unordered collections like [`HashMap`],
|
|
||||||
//! the items will be yielded in whatever order the internal representation made
|
|
||||||
//! most convenient. This is great for reading through all the contents of the
|
|
||||||
//! collection.
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! let vec = vec![1, 2, 3, 4];
|
|
||||||
//! for x in vec.iter() {
|
|
||||||
//! println!("vec contained {}", x);
|
|
||||||
//! }
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! `iter_mut` provides an iterator of *mutable* references in the same order as
|
|
||||||
//! `iter`. This is great for mutating all the contents of the collection.
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! let mut vec = vec![1, 2, 3, 4];
|
|
||||||
//! for x in vec.iter_mut() {
|
|
||||||
//! *x += 1;
|
|
||||||
//! }
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! `into_iter` transforms the actual collection into an iterator over its
|
|
||||||
//! contents by-value. This is great when the collection itself is no longer
|
|
||||||
//! needed, and the values are needed elsewhere. Using `extend` with `into_iter`
|
|
||||||
//! is the main way that contents of one collection are moved into another.
|
|
||||||
//! `extend` automatically calls `into_iter`, and takes any `T: `[`IntoIterator`].
|
|
||||||
//! Calling `collect` on an iterator itself is also a great way to convert one
|
|
||||||
//! collection into another. Both of these methods should internally use the
|
|
||||||
//! capacity management tools discussed in the previous section to do this as
|
|
||||||
//! efficiently as possible.
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! let mut vec1 = vec![1, 2, 3, 4];
|
|
||||||
//! let vec2 = vec![10, 20, 30, 40];
|
|
||||||
//! vec1.extend(vec2);
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! use std::collections::VecDeque;
|
|
||||||
//!
|
|
||||||
//! let vec = vec![1, 2, 3, 4];
|
|
||||||
//! let buf: VecDeque<_> = vec.into_iter().collect();
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! Iterators also provide a series of *adapter* methods for performing common
|
|
||||||
//! threads to sequences. Among the adapters are functional favorites like `map`,
|
|
||||||
//! `fold`, `skip` and `take`. Of particular interest to collections is the
|
|
||||||
//! `rev` adapter, that reverses any iterator that supports this operation. Most
|
|
||||||
//! collections provide reversible iterators as the way to iterate over them in
|
|
||||||
//! reverse order.
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! let vec = vec![1, 2, 3, 4];
|
|
||||||
//! for x in vec.iter().rev() {
|
|
||||||
//! println!("vec contained {}", x);
|
|
||||||
//! }
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! Several other collection methods also return iterators to yield a sequence
|
|
||||||
//! of results but avoid allocating an entire collection to store the result in.
|
|
||||||
//! This provides maximum flexibility as `collect` or `extend` can be called to
|
|
||||||
//! "pipe" the sequence into any collection if desired. Otherwise, the sequence
|
|
||||||
//! can be looped over with a `for` loop. The iterator can also be discarded
|
|
||||||
//! after partial use, preventing the computation of the unused items.
|
|
||||||
//!
|
|
||||||
//! ## Entries
|
|
||||||
//!
|
|
||||||
//! The `entry` API is intended to provide an efficient mechanism for
|
|
||||||
//! manipulating the contents of a map conditionally on the presence of a key or
|
|
||||||
//! not. The primary motivating use case for this is to provide efficient
|
|
||||||
//! accumulator maps. For instance, if one wishes to maintain a count of the
|
|
||||||
//! number of times each key has been seen, they will have to perform some
|
|
||||||
//! conditional logic on whether this is the first time the key has been seen or
|
|
||||||
//! not. Normally, this would require a `find` followed by an `insert`,
|
|
||||||
//! effectively duplicating the search effort on each insertion.
|
|
||||||
//!
|
|
||||||
//! When a user calls `map.entry(&key)`, the map will search for the key and
|
|
||||||
//! then yield a variant of the `Entry` enum.
|
|
||||||
//!
|
|
||||||
//! If a `Vacant(entry)` is yielded, then the key *was not* found. In this case
|
|
||||||
//! the only valid operation is to `insert` a value into the entry. When this is
|
|
||||||
//! done, the vacant entry is consumed and converted into a mutable reference to
|
|
||||||
//! the value that was inserted. This allows for further manipulation of the
|
|
||||||
//! value beyond the lifetime of the search itself. This is useful if complex
|
|
||||||
//! logic needs to be performed on the value regardless of whether the value was
|
|
||||||
//! just inserted.
|
|
||||||
//!
|
|
||||||
//! If an `Occupied(entry)` is yielded, then the key *was* found. In this case,
|
|
||||||
//! the user has several options: they can `get`, `insert` or `remove` the
|
|
||||||
//! value of the occupied entry. Additionally, they can convert the occupied
|
|
||||||
//! entry into a mutable reference to its value, providing symmetry to the
|
|
||||||
//! vacant `insert` case.
|
|
||||||
//!
|
|
||||||
//! ### Examples
|
|
||||||
//!
|
|
||||||
//! Here are the two primary ways in which `entry` is used. First, a simple
|
|
||||||
//! example where the logic performed on the values is trivial.
|
|
||||||
//!
|
|
||||||
//! #### Counting the number of times each character in a string occurs
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! use std::collections::btree_map::BTreeMap;
|
|
||||||
//!
|
|
||||||
//! let mut count = BTreeMap::new();
|
|
||||||
//! let message = "she sells sea shells by the sea shore";
|
|
||||||
//!
|
|
||||||
//! for c in message.chars() {
|
|
||||||
//! *count.entry(c).or_insert(0) += 1;
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! assert_eq!(count.get(&'s'), Some(&8));
|
|
||||||
//!
|
|
||||||
//! println!("Number of occurrences of each character");
|
|
||||||
//! for (char, count) in &count {
|
|
||||||
//! println!("{}: {}", char, count);
|
|
||||||
//! }
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! When the logic to be performed on the value is more complex, we may simply
|
|
||||||
//! use the `entry` API to ensure that the value is initialized and perform the
|
|
||||||
//! logic afterwards.
|
|
||||||
//!
|
|
||||||
//! #### Tracking the inebriation of customers at a bar
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! use std::collections::btree_map::BTreeMap;
|
|
||||||
//!
|
|
||||||
//! // A client of the bar. They have a blood alcohol level.
|
|
||||||
//! struct Person { blood_alcohol: f32 }
|
|
||||||
//!
|
|
||||||
//! // All the orders made to the bar, by client id.
|
|
||||||
//! let orders = vec![1,2,1,2,3,4,1,2,2,3,4,1,1,1];
|
|
||||||
//!
|
|
||||||
//! // Our clients.
|
|
||||||
//! let mut blood_alcohol = BTreeMap::new();
|
|
||||||
//!
|
|
||||||
//! for id in orders {
|
|
||||||
//! // If this is the first time we've seen this customer, initialize them
|
|
||||||
//! // with no blood alcohol. Otherwise, just retrieve them.
|
|
||||||
//! let person = blood_alcohol.entry(id).or_insert(Person { blood_alcohol: 0.0 });
|
|
||||||
//!
|
|
||||||
//! // Reduce their blood alcohol level. It takes time to order and drink a beer!
|
|
||||||
//! person.blood_alcohol *= 0.9;
|
|
||||||
//!
|
|
||||||
//! // Check if they're sober enough to have another beer.
|
|
||||||
//! if person.blood_alcohol > 0.3 {
|
|
||||||
//! // Too drunk... for now.
|
|
||||||
//! println!("Sorry {}, I have to cut you off", id);
|
|
||||||
//! } else {
|
|
||||||
//! // Have another!
|
|
||||||
//! person.blood_alcohol += 0.1;
|
|
||||||
//! }
|
|
||||||
//! }
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! # Insert and complex keys
|
|
||||||
//!
|
|
||||||
//! If we have a more complex key, calls to `insert` will
|
|
||||||
//! not update the value of the key. For example:
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! use std::cmp::Ordering;
|
|
||||||
//! use std::collections::BTreeMap;
|
|
||||||
//! use std::hash::{Hash, Hasher};
|
|
||||||
//!
|
|
||||||
//! #[derive(Debug)]
|
|
||||||
//! struct Foo {
|
|
||||||
//! a: u32,
|
|
||||||
//! b: &'static str,
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! // we will compare `Foo`s by their `a` value only.
|
|
||||||
//! impl PartialEq for Foo {
|
|
||||||
//! fn eq(&self, other: &Self) -> bool { self.a == other.a }
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! impl Eq for Foo {}
|
|
||||||
//!
|
|
||||||
//! // we will hash `Foo`s by their `a` value only.
|
|
||||||
//! impl Hash for Foo {
|
|
||||||
//! fn hash<H: Hasher>(&self, h: &mut H) { self.a.hash(h); }
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! impl PartialOrd for Foo {
|
|
||||||
//! fn partial_cmp(&self, other: &Self) -> Option<Ordering> { self.a.partial_cmp(&other.a) }
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! impl Ord for Foo {
|
|
||||||
//! fn cmp(&self, other: &Self) -> Ordering { self.a.cmp(&other.a) }
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! let mut map = BTreeMap::new();
|
|
||||||
//! map.insert(Foo { a: 1, b: "baz" }, 99);
|
|
||||||
//!
|
|
||||||
//! // We already have a Foo with an a of 1, so this will be updating the value.
|
|
||||||
//! map.insert(Foo { a: 1, b: "xyz" }, 100);
|
|
||||||
//!
|
|
||||||
//! // The value has been updated...
|
|
||||||
//! assert_eq!(map.values().next().unwrap(), &100);
|
|
||||||
//!
|
|
||||||
//! // ...but the key hasn't changed. b is still "baz", not "xyz".
|
|
||||||
//! assert_eq!(map.keys().next().unwrap().b, "baz");
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! [`Vec`]: ../../std/vec/struct.Vec.html
|
|
||||||
//! [`HashMap`]: ../../std/collections/struct.HashMap.html
|
|
||||||
//! [`VecDeque`]: ../../std/collections/struct.VecDeque.html
|
|
||||||
//! [`LinkedList`]: ../../std/collections/struct.LinkedList.html
|
|
||||||
//! [`BTreeMap`]: ../../std/collections/struct.BTreeMap.html
|
|
||||||
//! [`HashSet`]: ../../std/collections/struct.HashSet.html
|
|
||||||
//! [`BTreeSet`]: ../../std/collections/struct.BTreeSet.html
|
|
||||||
//! [`BinaryHeap`]: ../../std/collections/struct.BinaryHeap.html
|
|
||||||
//! [`IntoIterator`]: ../../std/iter/trait.IntoIterator.html
|
|
||||||
|
|
||||||
#![stable(feature = "rust1", since = "1.0.0")] |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#[rustc_deprecated(reason = "moved to `std::ops::Bound`", since = "1.26.0")] |
|
||||||
#[doc(hidden)] |
|
||||||
pub use ops::Bound; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use alloc_crate::collections::{BinaryHeap, BTreeMap, BTreeSet}; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use alloc_crate::collections::{LinkedList, VecDeque}; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use alloc_crate::collections::{binary_heap, btree_map, btree_set}; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use alloc_crate::collections::{linked_list, vec_deque}; |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use self::hash_map::HashMap; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use self::hash_set::HashSet; |
|
||||||
|
|
||||||
#[unstable(feature = "try_reserve", reason = "new API", issue="48043")] |
|
||||||
pub use alloc_crate::collections::CollectionAllocErr; |
|
||||||
|
|
||||||
mod hash; |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub mod hash_map { |
|
||||||
//! A hash map implemented with linear probing and Robin Hood bucket stealing.
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use super::hash::map::*; |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub mod hash_set { |
|
||||||
//! A hash set implemented as a `HashMap` where the value is `()`.
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use super::hash::set::*; |
|
||||||
} |
|
@ -1,548 +0,0 @@ |
|||||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Traits for working with Errors.
|
|
||||||
|
|
||||||
#![stable(feature = "rust1", since = "1.0.0")] |
|
||||||
|
|
||||||
// A note about crates and the facade:
|
|
||||||
//
|
|
||||||
// Originally, the `Error` trait was defined in libcore, and the impls
|
|
||||||
// were scattered about. However, coherence objected to this
|
|
||||||
// arrangement, because to create the blanket impls for `Box` required
|
|
||||||
// knowing that `&str: !Error`, and we have no means to deal with that
|
|
||||||
// sort of conflict just now. Therefore, for the time being, we have
|
|
||||||
// moved the `Error` trait into libstd. As we evolve a sol'n to the
|
|
||||||
// coherence challenge (e.g., specialization, neg impls, etc) we can
|
|
||||||
// reconsider what crate these items belong in.
|
|
||||||
|
|
||||||
use alloc::{AllocErr, LayoutErr, CannotReallocInPlace}; |
|
||||||
use any::TypeId; |
|
||||||
use borrow::Cow; |
|
||||||
use cell; |
|
||||||
use char; |
|
||||||
use core::array; |
|
||||||
use fmt::{self, Debug, Display}; |
|
||||||
use mem::transmute; |
|
||||||
use num; |
|
||||||
use str; |
|
||||||
use string; |
|
||||||
|
|
||||||
/// `Error` is a trait representing the basic expectations for error values,
|
|
||||||
/// i.e. values of type `E` in [`Result<T, E>`]. Errors must describe
|
|
||||||
/// themselves through the [`Display`] and [`Debug`] traits, and may provide
|
|
||||||
/// cause chain information:
|
|
||||||
///
|
|
||||||
/// The [`cause`] method is generally used when errors cross "abstraction
|
|
||||||
/// boundaries", i.e. when a one module must report an error that is "caused"
|
|
||||||
/// by an error from a lower-level module. This setup makes it possible for the
|
|
||||||
/// high-level module to provide its own errors that do not commit to any
|
|
||||||
/// particular implementation, but also reveal some of its implementation for
|
|
||||||
/// debugging via [`cause`] chains.
|
|
||||||
///
|
|
||||||
/// [`Result<T, E>`]: ../result/enum.Result.html
|
|
||||||
/// [`Display`]: ../fmt/trait.Display.html
|
|
||||||
/// [`Debug`]: ../fmt/trait.Debug.html
|
|
||||||
/// [`cause`]: trait.Error.html#method.cause
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub trait Error: Debug + Display { |
|
||||||
/// **This method is soft-deprecated.**
|
|
||||||
///
|
|
||||||
/// Although using it won’t cause compilation warning,
|
|
||||||
/// new code should use [`Display`] instead
|
|
||||||
/// and new `impl`s can omit it.
|
|
||||||
///
|
|
||||||
/// To obtain error description as a string, use `to_string()`.
|
|
||||||
///
|
|
||||||
/// [`Display`]: ../fmt/trait.Display.html
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// match "xc".parse::<u32>() {
|
|
||||||
/// Err(e) => {
|
|
||||||
/// // Print `e` itself, not `e.description()`.
|
|
||||||
/// println!("Error: {}", e);
|
|
||||||
/// }
|
|
||||||
/// _ => println!("No error"),
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
fn description(&self) -> &str { |
|
||||||
"description() is deprecated; use Display" |
|
||||||
} |
|
||||||
|
|
||||||
/// The lower-level cause of this error, if any.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::error::Error;
|
|
||||||
/// use std::fmt;
|
|
||||||
///
|
|
||||||
/// #[derive(Debug)]
|
|
||||||
/// struct SuperError {
|
|
||||||
/// side: SuperErrorSideKick,
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// impl fmt::Display for SuperError {
|
|
||||||
/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
/// write!(f, "SuperError is here!")
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// impl Error for SuperError {
|
|
||||||
/// fn description(&self) -> &str {
|
|
||||||
/// "I'm the superhero of errors"
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// fn cause(&self) -> Option<&Error> {
|
|
||||||
/// Some(&self.side)
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// #[derive(Debug)]
|
|
||||||
/// struct SuperErrorSideKick;
|
|
||||||
///
|
|
||||||
/// impl fmt::Display for SuperErrorSideKick {
|
|
||||||
/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
/// write!(f, "SuperErrorSideKick is here!")
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// impl Error for SuperErrorSideKick {
|
|
||||||
/// fn description(&self) -> &str {
|
|
||||||
/// "I'm SuperError side kick"
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// fn get_super_error() -> Result<(), SuperError> {
|
|
||||||
/// Err(SuperError { side: SuperErrorSideKick })
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// fn main() {
|
|
||||||
/// match get_super_error() {
|
|
||||||
/// Err(e) => {
|
|
||||||
/// println!("Error: {}", e.description());
|
|
||||||
/// println!("Caused by: {}", e.cause().unwrap());
|
|
||||||
/// }
|
|
||||||
/// _ => println!("No error"),
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
fn cause(&self) -> Option<&dyn Error> { None } |
|
||||||
|
|
||||||
/// Get the `TypeId` of `self`
|
|
||||||
#[doc(hidden)] |
|
||||||
#[unstable(feature = "error_type_id",
|
|
||||||
reason = "unclear whether to commit to this public implementation detail", |
|
||||||
issue = "27745")] |
|
||||||
fn type_id(&self) -> TypeId where Self: 'static { |
|
||||||
TypeId::of::<Self>() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> { |
|
||||||
fn from(err: E) -> Box<dyn Error + 'a> { |
|
||||||
Box::new(err) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> { |
|
||||||
fn from(err: E) -> Box<dyn Error + Send + Sync + 'a> { |
|
||||||
Box::new(err) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl From<String> for Box<dyn Error + Send + Sync> { |
|
||||||
fn from(err: String) -> Box<dyn Error + Send + Sync> { |
|
||||||
#[derive(Debug)] |
|
||||||
struct StringError(String); |
|
||||||
|
|
||||||
impl Error for StringError { |
|
||||||
fn description(&self) -> &str { &self.0 } |
|
||||||
} |
|
||||||
|
|
||||||
impl Display for StringError { |
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
|
||||||
Display::fmt(&self.0, f) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
Box::new(StringError(err)) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "string_box_error", since = "1.6.0")] |
|
||||||
impl From<String> for Box<dyn Error> { |
|
||||||
fn from(str_err: String) -> Box<dyn Error> { |
|
||||||
let err1: Box<dyn Error + Send + Sync> = From::from(str_err); |
|
||||||
let err2: Box<dyn Error> = err1; |
|
||||||
err2 |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl<'a, 'b> From<&'b str> for Box<dyn Error + Send + Sync + 'a> { |
|
||||||
fn from(err: &'b str) -> Box<dyn Error + Send + Sync + 'a> { |
|
||||||
From::from(String::from(err)) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "string_box_error", since = "1.6.0")] |
|
||||||
impl<'a> From<&'a str> for Box<dyn Error> { |
|
||||||
fn from(err: &'a str) -> Box<dyn Error> { |
|
||||||
From::from(String::from(err)) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "cow_box_error", since = "1.22.0")] |
|
||||||
impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> { |
|
||||||
fn from(err: Cow<'b, str>) -> Box<dyn Error + Send + Sync + 'a> { |
|
||||||
From::from(String::from(err)) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "cow_box_error", since = "1.22.0")] |
|
||||||
impl<'a> From<Cow<'a, str>> for Box<dyn Error> { |
|
||||||
fn from(err: Cow<'a, str>) -> Box<dyn Error> { |
|
||||||
From::from(String::from(err)) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[unstable(feature = "never_type", issue = "35121")] |
|
||||||
impl Error for ! { |
|
||||||
fn description(&self) -> &str { *self } |
|
||||||
} |
|
||||||
|
|
||||||
#[unstable(feature = "allocator_api",
|
|
||||||
reason = "the precise API and guarantees it provides may be tweaked.", |
|
||||||
issue = "32838")] |
|
||||||
impl Error for AllocErr { |
|
||||||
fn description(&self) -> &str { |
|
||||||
"memory allocation failed" |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[unstable(feature = "allocator_api",
|
|
||||||
reason = "the precise API and guarantees it provides may be tweaked.", |
|
||||||
issue = "32838")] |
|
||||||
impl Error for LayoutErr { |
|
||||||
fn description(&self) -> &str { |
|
||||||
"invalid parameters to Layout::from_size_align" |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[unstable(feature = "allocator_api",
|
|
||||||
reason = "the precise API and guarantees it provides may be tweaked.", |
|
||||||
issue = "32838")] |
|
||||||
impl Error for CannotReallocInPlace { |
|
||||||
fn description(&self) -> &str { |
|
||||||
CannotReallocInPlace::description(self) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl Error for str::ParseBoolError { |
|
||||||
fn description(&self) -> &str { "failed to parse bool" } |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl Error for str::Utf8Error { |
|
||||||
fn description(&self) -> &str { |
|
||||||
"invalid utf-8: corrupt contents" |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl Error for num::ParseIntError { |
|
||||||
fn description(&self) -> &str { |
|
||||||
self.__description() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[unstable(feature = "try_from", issue = "33417")] |
|
||||||
impl Error for num::TryFromIntError { |
|
||||||
fn description(&self) -> &str { |
|
||||||
self.__description() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[unstable(feature = "try_from", issue = "33417")] |
|
||||||
impl Error for array::TryFromSliceError { |
|
||||||
fn description(&self) -> &str { |
|
||||||
self.__description() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl Error for num::ParseFloatError { |
|
||||||
fn description(&self) -> &str { |
|
||||||
self.__description() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl Error for string::FromUtf8Error { |
|
||||||
fn description(&self) -> &str { |
|
||||||
"invalid utf-8" |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl Error for string::FromUtf16Error { |
|
||||||
fn description(&self) -> &str { |
|
||||||
"invalid utf-16" |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "str_parse_error2", since = "1.8.0")] |
|
||||||
impl Error for string::ParseError { |
|
||||||
fn description(&self) -> &str { |
|
||||||
match *self {} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "decode_utf16", since = "1.9.0")] |
|
||||||
impl Error for char::DecodeUtf16Error { |
|
||||||
fn description(&self) -> &str { |
|
||||||
"unpaired surrogate found" |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "box_error", since = "1.8.0")] |
|
||||||
impl<T: Error> Error for Box<T> { |
|
||||||
fn description(&self) -> &str { |
|
||||||
Error::description(&**self) |
|
||||||
} |
|
||||||
|
|
||||||
fn cause(&self) -> Option<&dyn Error> { |
|
||||||
Error::cause(&**self) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "fmt_error", since = "1.11.0")] |
|
||||||
impl Error for fmt::Error { |
|
||||||
fn description(&self) -> &str { |
|
||||||
"an error occurred when formatting an argument" |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "try_borrow", since = "1.13.0")] |
|
||||||
impl Error for cell::BorrowError { |
|
||||||
fn description(&self) -> &str { |
|
||||||
"already mutably borrowed" |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "try_borrow", since = "1.13.0")] |
|
||||||
impl Error for cell::BorrowMutError { |
|
||||||
fn description(&self) -> &str { |
|
||||||
"already borrowed" |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[unstable(feature = "try_from", issue = "33417")] |
|
||||||
impl Error for char::CharTryFromError { |
|
||||||
fn description(&self) -> &str { |
|
||||||
"converted integer out of range for `char`" |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "char_from_str", since = "1.20.0")] |
|
||||||
impl Error for char::ParseCharError { |
|
||||||
fn description(&self) -> &str { |
|
||||||
self.__description() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// copied from any.rs
|
|
||||||
impl dyn Error + 'static { |
|
||||||
/// Returns true if the boxed type is the same as `T`
|
|
||||||
#[stable(feature = "error_downcast", since = "1.3.0")] |
|
||||||
#[inline] |
|
||||||
pub fn is<T: Error + 'static>(&self) -> bool { |
|
||||||
// Get TypeId of the type this function is instantiated with
|
|
||||||
let t = TypeId::of::<T>(); |
|
||||||
|
|
||||||
// Get TypeId of the type in the trait object
|
|
||||||
let boxed = self.type_id(); |
|
||||||
|
|
||||||
// Compare both TypeIds on equality
|
|
||||||
t == boxed |
|
||||||
} |
|
||||||
|
|
||||||
/// Returns some reference to the boxed value if it is of type `T`, or
|
|
||||||
/// `None` if it isn't.
|
|
||||||
#[stable(feature = "error_downcast", since = "1.3.0")] |
|
||||||
#[inline] |
|
||||||
pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> { |
|
||||||
if self.is::<T>() { |
|
||||||
unsafe { |
|
||||||
Some(&*(self as *const dyn Error as *const T)) |
|
||||||
} |
|
||||||
} else { |
|
||||||
None |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// Returns some mutable reference to the boxed value if it is of type `T`, or
|
|
||||||
/// `None` if it isn't.
|
|
||||||
#[stable(feature = "error_downcast", since = "1.3.0")] |
|
||||||
#[inline] |
|
||||||
pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> { |
|
||||||
if self.is::<T>() { |
|
||||||
unsafe { |
|
||||||
Some(&mut *(self as *mut dyn Error as *mut T)) |
|
||||||
} |
|
||||||
} else { |
|
||||||
None |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl dyn Error + 'static + Send { |
|
||||||
/// Forwards to the method defined on the type `Any`.
|
|
||||||
#[stable(feature = "error_downcast", since = "1.3.0")] |
|
||||||
#[inline] |
|
||||||
pub fn is<T: Error + 'static>(&self) -> bool { |
|
||||||
<dyn Error + 'static>::is::<T>(self) |
|
||||||
} |
|
||||||
|
|
||||||
/// Forwards to the method defined on the type `Any`.
|
|
||||||
#[stable(feature = "error_downcast", since = "1.3.0")] |
|
||||||
#[inline] |
|
||||||
pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> { |
|
||||||
<dyn Error + 'static>::downcast_ref::<T>(self) |
|
||||||
} |
|
||||||
|
|
||||||
/// Forwards to the method defined on the type `Any`.
|
|
||||||
#[stable(feature = "error_downcast", since = "1.3.0")] |
|
||||||
#[inline] |
|
||||||
pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> { |
|
||||||
<dyn Error + 'static>::downcast_mut::<T>(self) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl dyn Error + 'static + Send + Sync { |
|
||||||
/// Forwards to the method defined on the type `Any`.
|
|
||||||
#[stable(feature = "error_downcast", since = "1.3.0")] |
|
||||||
#[inline] |
|
||||||
pub fn is<T: Error + 'static>(&self) -> bool { |
|
||||||
<dyn Error + 'static>::is::<T>(self) |
|
||||||
} |
|
||||||
|
|
||||||
/// Forwards to the method defined on the type `Any`.
|
|
||||||
#[stable(feature = "error_downcast", since = "1.3.0")] |
|
||||||
#[inline] |
|
||||||
pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> { |
|
||||||
<dyn Error + 'static>::downcast_ref::<T>(self) |
|
||||||
} |
|
||||||
|
|
||||||
/// Forwards to the method defined on the type `Any`.
|
|
||||||
#[stable(feature = "error_downcast", since = "1.3.0")] |
|
||||||
#[inline] |
|
||||||
pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> { |
|
||||||
<dyn Error + 'static>::downcast_mut::<T>(self) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl dyn Error { |
|
||||||
#[inline] |
|
||||||
#[stable(feature = "error_downcast", since = "1.3.0")] |
|
||||||
/// Attempt to downcast the box to a concrete type.
|
|
||||||
pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error>> { |
|
||||||
if self.is::<T>() { |
|
||||||
unsafe { |
|
||||||
let raw: *mut dyn Error = Box::into_raw(self); |
|
||||||
Ok(Box::from_raw(raw as *mut T)) |
|
||||||
} |
|
||||||
} else { |
|
||||||
Err(self) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl dyn Error + Send { |
|
||||||
#[inline] |
|
||||||
#[stable(feature = "error_downcast", since = "1.3.0")] |
|
||||||
/// Attempt to downcast the box to a concrete type.
|
|
||||||
pub fn downcast<T: Error + 'static>(self: Box<Self>) |
|
||||||
-> Result<Box<T>, Box<dyn Error + Send>> { |
|
||||||
let err: Box<dyn Error> = self; |
|
||||||
<dyn Error>::downcast(err).map_err(|s| unsafe { |
|
||||||
// reapply the Send marker
|
|
||||||
transmute::<Box<dyn Error>, Box<dyn Error + Send>>(s) |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl dyn Error + Send + Sync { |
|
||||||
#[inline] |
|
||||||
#[stable(feature = "error_downcast", since = "1.3.0")] |
|
||||||
/// Attempt to downcast the box to a concrete type.
|
|
||||||
pub fn downcast<T: Error + 'static>(self: Box<Self>) |
|
||||||
-> Result<Box<T>, Box<Self>> { |
|
||||||
let err: Box<dyn Error> = self; |
|
||||||
<dyn Error>::downcast(err).map_err(|s| unsafe { |
|
||||||
// reapply the Send+Sync marker
|
|
||||||
transmute::<Box<dyn Error>, Box<dyn Error + Send + Sync>>(s) |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(test)] |
|
||||||
mod tests { |
|
||||||
use super::Error; |
|
||||||
use fmt; |
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)] |
|
||||||
struct A; |
|
||||||
#[derive(Debug, PartialEq)] |
|
||||||
struct B; |
|
||||||
|
|
||||||
impl fmt::Display for A { |
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
|
||||||
write!(f, "A") |
|
||||||
} |
|
||||||
} |
|
||||||
impl fmt::Display for B { |
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
|
||||||
write!(f, "B") |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl Error for A { |
|
||||||
fn description(&self) -> &str { "A-desc" } |
|
||||||
} |
|
||||||
impl Error for B { |
|
||||||
fn description(&self) -> &str { "A-desc" } |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn downcasting() { |
|
||||||
let mut a = A; |
|
||||||
let a = &mut a as &mut (dyn Error + 'static); |
|
||||||
assert_eq!(a.downcast_ref::<A>(), Some(&A)); |
|
||||||
assert_eq!(a.downcast_ref::<B>(), None); |
|
||||||
assert_eq!(a.downcast_mut::<A>(), Some(&mut A)); |
|
||||||
assert_eq!(a.downcast_mut::<B>(), None); |
|
||||||
|
|
||||||
let a: Box<dyn Error> = Box::new(A); |
|
||||||
match a.downcast::<B>() { |
|
||||||
Ok(..) => panic!("expected error"), |
|
||||||
Err(e) => assert_eq!(*e.downcast::<A>().unwrap(), A), |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,175 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Utilities related to FFI bindings.
|
|
||||||
//!
|
|
||||||
//! This module provides utilities to handle data across non-Rust
|
|
||||||
//! interfaces, like other programming languages and the underlying
|
|
||||||
//! operating system. It is mainly of use for FFI (Foreign Function
|
|
||||||
//! Interface) bindings and code that needs to exchange C-like strings
|
|
||||||
//! with other languages.
|
|
||||||
//!
|
|
||||||
//! # Overview
|
|
||||||
//!
|
|
||||||
//! Rust represents owned strings with the [`String`] type, and
|
|
||||||
//! borrowed slices of strings with the [`str`] primitive. Both are
|
|
||||||
//! always in UTF-8 encoding, and may contain nul bytes in the middle,
|
|
||||||
//! i.e. if you look at the bytes that make up the string, there may
|
|
||||||
//! be a `\0` among them. Both `String` and `str` store their length
|
|
||||||
//! explicitly; there are no nul terminators at the end of strings
|
|
||||||
//! like in C.
|
|
||||||
//!
|
|
||||||
//! C strings are different from Rust strings:
|
|
||||||
//!
|
|
||||||
//! * **Encodings** - Rust strings are UTF-8, but C strings may use
|
|
||||||
//! other encodings. If you are using a string from C, you should
|
|
||||||
//! check its encoding explicitly, rather than just assuming that it
|
|
||||||
//! is UTF-8 like you can do in Rust.
|
|
||||||
//!
|
|
||||||
//! * **Character size** - C strings may use `char` or `wchar_t`-sized
|
|
||||||
//! characters; please **note** that C's `char` is different from Rust's.
|
|
||||||
//! The C standard leaves the actual sizes of those types open to
|
|
||||||
//! interpretation, but defines different APIs for strings made up of
|
|
||||||
//! each character type. Rust strings are always UTF-8, so different
|
|
||||||
//! Unicode characters will be encoded in a variable number of bytes
|
|
||||||
//! each. The Rust type [`char`] represents a '[Unicode scalar
|
|
||||||
//! value]', which is similar to, but not the same as, a '[Unicode
|
|
||||||
//! code point]'.
|
|
||||||
//!
|
|
||||||
//! * **Nul terminators and implicit string lengths** - Often, C
|
|
||||||
//! strings are nul-terminated, i.e. they have a `\0` character at the
|
|
||||||
//! end. The length of a string buffer is not stored, but has to be
|
|
||||||
//! calculated; to compute the length of a string, C code must
|
|
||||||
//! manually call a function like `strlen()` for `char`-based strings,
|
|
||||||
//! or `wcslen()` for `wchar_t`-based ones. Those functions return
|
|
||||||
//! the number of characters in the string excluding the nul
|
|
||||||
//! terminator, so the buffer length is really `len+1` characters.
|
|
||||||
//! Rust strings don't have a nul terminator; their length is always
|
|
||||||
//! stored and does not need to be calculated. While in Rust
|
|
||||||
//! accessing a string's length is a O(1) operation (because the
|
|
||||||
//! length is stored); in C it is an O(length) operation because the
|
|
||||||
//! length needs to be computed by scanning the string for the nul
|
|
||||||
//! terminator.
|
|
||||||
//!
|
|
||||||
//! * **Internal nul characters** - When C strings have a nul
|
|
||||||
//! terminator character, this usually means that they cannot have nul
|
|
||||||
//! characters in the middle — a nul character would essentially
|
|
||||||
//! truncate the string. Rust strings *can* have nul characters in
|
|
||||||
//! the middle, because nul does not have to mark the end of the
|
|
||||||
//! string in Rust.
|
|
||||||
//!
|
|
||||||
//! # Representations of non-Rust strings
|
|
||||||
//!
|
|
||||||
//! [`CString`] and [`CStr`] are useful when you need to transfer
|
|
||||||
//! UTF-8 strings to and from languages with a C ABI, like Python.
|
|
||||||
//!
|
|
||||||
//! * **From Rust to C:** [`CString`] represents an owned, C-friendly
|
|
||||||
//! string: it is nul-terminated, and has no internal nul characters.
|
|
||||||
//! Rust code can create a `CString` out of a normal string (provided
|
|
||||||
//! that the string doesn't have nul characters in the middle), and
|
|
||||||
//! then use a variety of methods to obtain a raw `*mut u8` that can
|
|
||||||
//! then be passed as an argument to functions which use the C
|
|
||||||
//! conventions for strings.
|
|
||||||
//!
|
|
||||||
//! * **From C to Rust:** [`CStr`] represents a borrowed C string; it
|
|
||||||
//! is what you would use to wrap a raw `*const u8` that you got from
|
|
||||||
//! a C function. A `CStr` is guaranteed to be a nul-terminated array
|
|
||||||
//! of bytes. Once you have a `CStr`, you can convert it to a Rust
|
|
||||||
//! `&str` if it's valid UTF-8, or lossily convert it by adding
|
|
||||||
//! replacement characters.
|
|
||||||
//!
|
|
||||||
//! [`OsString`] and [`OsStr`] are useful when you need to transfer
|
|
||||||
//! strings to and from the operating system itself, or when capturing
|
|
||||||
//! the output of external commands. Conversions between `OsString`,
|
|
||||||
//! `OsStr` and Rust strings work similarly to those for [`CString`]
|
|
||||||
//! and [`CStr`].
|
|
||||||
//!
|
|
||||||
//! * [`OsString`] represents an owned string in whatever
|
|
||||||
//! representation the operating system prefers. In the Rust standard
|
|
||||||
//! library, various APIs that transfer strings to/from the operating
|
|
||||||
//! system use `OsString` instead of plain strings. For example,
|
|
||||||
//! [`env::var_os()`] is used to query environment variables; it
|
|
||||||
//! returns an `Option<OsString>`. If the environment variable exists
|
|
||||||
//! you will get a `Some(os_string)`, which you can *then* try to
|
|
||||||
//! convert to a Rust string. This yields a [`Result<>`], so that
|
|
||||||
//! your code can detect errors in case the environment variable did
|
|
||||||
//! not in fact contain valid Unicode data.
|
|
||||||
//!
|
|
||||||
//! * [`OsStr`] represents a borrowed reference to a string in a
|
|
||||||
//! format that can be passed to the operating system. It can be
|
|
||||||
//! converted into an UTF-8 Rust string slice in a similar way to
|
|
||||||
//! `OsString`.
|
|
||||||
//!
|
|
||||||
//! # Conversions
|
|
||||||
//!
|
|
||||||
//! ## On Unix
|
|
||||||
//!
|
|
||||||
//! On Unix, [`OsStr`] implements the
|
|
||||||
//! `std::os::unix:ffi::`[`OsStrExt`][unix.OsStrExt] trait, which
|
|
||||||
//! augments it with two methods, [`from_bytes`] and [`as_bytes`].
|
|
||||||
//! These do inexpensive conversions from and to UTF-8 byte slices.
|
|
||||||
//!
|
|
||||||
//! Additionally, on Unix [`OsString`] implements the
|
|
||||||
//! `std::os::unix:ffi::`[`OsStringExt`][unix.OsStringExt] trait,
|
|
||||||
//! which provides [`from_vec`] and [`into_vec`] methods that consume
|
|
||||||
//! their arguments, and take or produce vectors of [`u8`].
|
|
||||||
//!
|
|
||||||
//! ## On Windows
|
|
||||||
//!
|
|
||||||
//! On Windows, [`OsStr`] implements the
|
|
||||||
//! `std::os::windows::ffi::`[`OsStrExt`][windows.OsStrExt] trait,
|
|
||||||
//! which provides an [`encode_wide`] method. This provides an
|
|
||||||
//! iterator that can be [`collect`]ed into a vector of [`u16`].
|
|
||||||
//!
|
|
||||||
//! Additionally, on Windows [`OsString`] implements the
|
|
||||||
//! `std::os::windows:ffi::`[`OsStringExt`][windows.OsStringExt]
|
|
||||||
//! trait, which provides a [`from_wide`] method. The result of this
|
|
||||||
//! method is an `OsString` which can be round-tripped to a Windows
|
|
||||||
//! string losslessly.
|
|
||||||
//!
|
|
||||||
//! [`String`]: ../string/struct.String.html
|
|
||||||
//! [`str`]: ../primitive.str.html
|
|
||||||
//! [`char`]: ../primitive.char.html
|
|
||||||
//! [`u8`]: ../primitive.u8.html
|
|
||||||
//! [`u16`]: ../primitive.u16.html
|
|
||||||
//! [Unicode scalar value]: http://www.unicode.org/glossary/#unicode_scalar_value
|
|
||||||
//! [Unicode code point]: http://www.unicode.org/glossary/#code_point
|
|
||||||
//! [`CString`]: struct.CString.html
|
|
||||||
//! [`CStr`]: struct.CStr.html
|
|
||||||
//! [`OsString`]: struct.OsString.html
|
|
||||||
//! [`OsStr`]: struct.OsStr.html
|
|
||||||
//! [`env::set_var()`]: ../env/fn.set_var.html
|
|
||||||
//! [`env::var_os()`]: ../env/fn.var_os.html
|
|
||||||
//! [`Result<>`]: ../result/enum.Result.html
|
|
||||||
//! [unix.OsStringExt]: ../os/unix/ffi/trait.OsStringExt.html
|
|
||||||
//! [`from_vec`]: ../os/unix/ffi/trait.OsStringExt.html#tymethod.from_vec
|
|
||||||
//! [`into_vec`]: ../os/unix/ffi/trait.OsStringExt.html#tymethod.into_vec
|
|
||||||
//! [unix.OsStrExt]: ../os/unix/ffi/trait.OsStrExt.html
|
|
||||||
//! [`from_bytes`]: ../os/unix/ffi/trait.OsStrExt.html#tymethod.from_bytes
|
|
||||||
//! [`as_bytes`]: ../os/unix/ffi/trait.OsStrExt.html#tymethod.as_bytes
|
|
||||||
//! [`OsStrExt`]: ../os/unix/ffi/trait.OsStrExt.html
|
|
||||||
//! [windows.OsStrExt]: ../os/windows/ffi/trait.OsStrExt.html
|
|
||||||
//! [`encode_wide`]: ../os/windows/ffi/trait.OsStrExt.html#tymethod.encode_wide
|
|
||||||
//! [`collect`]: ../iter/trait.Iterator.html#method.collect
|
|
||||||
//! [windows.OsStringExt]: ../os/windows/ffi/trait.OsStringExt.html
|
|
||||||
//! [`from_wide`]: ../os/windows/ffi/trait.OsStringExt.html#tymethod.from_wide
|
|
||||||
|
|
||||||
#![stable(feature = "rust1", since = "1.0.0")] |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use self::c_str::{CString, CStr, NulError, IntoStringError}; |
|
||||||
#[stable(feature = "cstr_from_bytes", since = "1.10.0")] |
|
||||||
pub use self::c_str::{FromBytesWithNulError}; |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use self::os_str::{OsString, OsStr}; |
|
||||||
|
|
||||||
mod c_str; |
|
||||||
mod os_str; |
|
@ -1,116 +0,0 @@ |
|||||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Asynchronous values.
|
|
||||||
|
|
||||||
use core::cell::Cell; |
|
||||||
use core::marker::Unpin; |
|
||||||
use core::mem::PinMut; |
|
||||||
use core::option::Option; |
|
||||||
use core::ptr::NonNull; |
|
||||||
use core::task::{self, Poll}; |
|
||||||
use core::ops::{Drop, Generator, GeneratorState}; |
|
||||||
|
|
||||||
#[doc(inline)] |
|
||||||
pub use core::future::*; |
|
||||||
|
|
||||||
/// Wrap a future in a generator.
|
|
||||||
///
|
|
||||||
/// This function returns a `GenFuture` underneath, but hides it in `impl Trait` to give
|
|
||||||
/// better error messages (`impl Future` rather than `GenFuture<[closure.....]>`).
|
|
||||||
#[unstable(feature = "gen_future", issue = "50547")] |
|
||||||
pub fn from_generator<T: Generator<Yield = ()>>(x: T) -> impl Future<Output = T::Return> { |
|
||||||
GenFuture(x) |
|
||||||
} |
|
||||||
|
|
||||||
/// A wrapper around generators used to implement `Future` for `async`/`await` code.
|
|
||||||
#[unstable(feature = "gen_future", issue = "50547")] |
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] |
|
||||||
struct GenFuture<T: Generator<Yield = ()>>(T); |
|
||||||
|
|
||||||
// We rely on the fact that async/await futures are immovable in order to create
|
|
||||||
// self-referential borrows in the underlying generator.
|
|
||||||
impl<T: Generator<Yield = ()>> !Unpin for GenFuture<T> {} |
|
||||||
|
|
||||||
#[unstable(feature = "gen_future", issue = "50547")] |
|
||||||
impl<T: Generator<Yield = ()>> Future for GenFuture<T> { |
|
||||||
type Output = T::Return; |
|
||||||
fn poll(self: PinMut<Self>, cx: &mut task::Context) -> Poll<Self::Output> { |
|
||||||
set_task_cx(cx, || match unsafe { PinMut::get_mut_unchecked(self).0.resume() } { |
|
||||||
GeneratorState::Yielded(()) => Poll::Pending, |
|
||||||
GeneratorState::Complete(x) => Poll::Ready(x), |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
thread_local! { |
|
||||||
static TLS_CX: Cell<Option<NonNull<task::Context<'static>>>> = Cell::new(None); |
|
||||||
} |
|
||||||
|
|
||||||
struct SetOnDrop(Option<NonNull<task::Context<'static>>>); |
|
||||||
|
|
||||||
impl Drop for SetOnDrop { |
|
||||||
fn drop(&mut self) { |
|
||||||
TLS_CX.with(|tls_cx| { |
|
||||||
tls_cx.set(self.0.take()); |
|
||||||
}); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[unstable(feature = "gen_future", issue = "50547")] |
|
||||||
/// Sets the thread-local task context used by async/await futures.
|
|
||||||
pub fn set_task_cx<F, R>(cx: &mut task::Context, f: F) -> R |
|
||||||
where |
|
||||||
F: FnOnce() -> R |
|
||||||
{ |
|
||||||
let old_cx = TLS_CX.with(|tls_cx| { |
|
||||||
tls_cx.replace(NonNull::new( |
|
||||||
cx |
|
||||||
as *mut task::Context |
|
||||||
as *mut () |
|
||||||
as *mut task::Context<'static> |
|
||||||
)) |
|
||||||
}); |
|
||||||
let _reset_cx = SetOnDrop(old_cx); |
|
||||||
f() |
|
||||||
} |
|
||||||
|
|
||||||
#[unstable(feature = "gen_future", issue = "50547")] |
|
||||||
/// Retrieves the thread-local task context used by async/await futures.
|
|
||||||
///
|
|
||||||
/// This function acquires exclusive access to the task context.
|
|
||||||
///
|
|
||||||
/// Panics if no task has been set or if the task context has already been
|
|
||||||
/// retrived by a surrounding call to get_task_cx.
|
|
||||||
pub fn get_task_cx<F, R>(f: F) -> R |
|
||||||
where |
|
||||||
F: FnOnce(&mut task::Context) -> R |
|
||||||
{ |
|
||||||
let cx_ptr = TLS_CX.with(|tls_cx| { |
|
||||||
// Clear the entry so that nested `with_get_cx` calls
|
|
||||||
// will fail or set their own value.
|
|
||||||
tls_cx.replace(None) |
|
||||||
}); |
|
||||||
let _reset_cx = SetOnDrop(cx_ptr); |
|
||||||
|
|
||||||
let mut cx_ptr = cx_ptr.expect( |
|
||||||
"TLS task::Context not set. This is a rustc bug. \ |
|
||||||
Please file an issue on https://github.com/rust-lang/rust.");
|
|
||||||
unsafe { f(cx_ptr.as_mut()) } |
|
||||||
} |
|
||||||
|
|
||||||
#[unstable(feature = "gen_future", issue = "50547")] |
|
||||||
/// Polls a future in the current thread-local task context.
|
|
||||||
pub fn poll_in_task_cx<F>(f: PinMut<F>) -> Poll<F::Output> |
|
||||||
where |
|
||||||
F: Future |
|
||||||
{ |
|
||||||
get_task_cx(|cx| f.poll(cx)) |
|
||||||
} |
|
@ -1,682 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
use io::prelude::*; |
|
||||||
|
|
||||||
use core::convert::TryInto; |
|
||||||
use cmp; |
|
||||||
use io::{self, Initializer, SeekFrom, Error, ErrorKind}; |
|
||||||
|
|
||||||
/// A `Cursor` wraps an in-memory buffer and provides it with a
|
|
||||||
/// [`Seek`] implementation.
|
|
||||||
///
|
|
||||||
/// `Cursor`s are used with in-memory buffers, anything implementing
|
|
||||||
/// `AsRef<[u8]>`, to allow them to implement [`Read`] and/or [`Write`],
|
|
||||||
/// allowing these buffers to be used anywhere you might use a reader or writer
|
|
||||||
/// that does actual I/O.
|
|
||||||
///
|
|
||||||
/// The standard library implements some I/O traits on various types which
|
|
||||||
/// are commonly used as a buffer, like `Cursor<`[`Vec`]`<u8>>` and
|
|
||||||
/// `Cursor<`[`&[u8]`][bytes]`>`.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// We may want to write bytes to a [`File`] in our production
|
|
||||||
/// code, but use an in-memory buffer in our tests. We can do this with
|
|
||||||
/// `Cursor`:
|
|
||||||
///
|
|
||||||
/// [`Seek`]: trait.Seek.html
|
|
||||||
/// [`Read`]: ../../std/io/trait.Read.html
|
|
||||||
/// [`Write`]: ../../std/io/trait.Write.html
|
|
||||||
/// [`Vec`]: ../../std/vec/struct.Vec.html
|
|
||||||
/// [bytes]: ../../std/primitive.slice.html
|
|
||||||
/// [`File`]: ../fs/struct.File.html
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::io::prelude::*;
|
|
||||||
/// use std::io::{self, SeekFrom};
|
|
||||||
/// use std::fs::File;
|
|
||||||
///
|
|
||||||
/// // a library function we've written
|
|
||||||
/// fn write_ten_bytes_at_end<W: Write + Seek>(writer: &mut W) -> io::Result<()> {
|
|
||||||
/// writer.seek(SeekFrom::End(-10))?;
|
|
||||||
///
|
|
||||||
/// for i in 0..10 {
|
|
||||||
/// writer.write(&[i])?;
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// // all went well
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// # fn foo() -> io::Result<()> {
|
|
||||||
/// // Here's some code that uses this library function.
|
|
||||||
/// //
|
|
||||||
/// // We might want to use a BufReader here for efficiency, but let's
|
|
||||||
/// // keep this example focused.
|
|
||||||
/// let mut file = File::create("foo.txt")?;
|
|
||||||
///
|
|
||||||
/// write_ten_bytes_at_end(&mut file)?;
|
|
||||||
/// # Ok(())
|
|
||||||
/// # }
|
|
||||||
///
|
|
||||||
/// // now let's write a test
|
|
||||||
/// #[test]
|
|
||||||
/// fn test_writes_bytes() {
|
|
||||||
/// // setting up a real File is much slower than an in-memory buffer,
|
|
||||||
/// // let's use a cursor instead
|
|
||||||
/// use std::io::Cursor;
|
|
||||||
/// let mut buff = Cursor::new(vec![0; 15]);
|
|
||||||
///
|
|
||||||
/// write_ten_bytes_at_end(&mut buff).unwrap();
|
|
||||||
///
|
|
||||||
/// assert_eq!(&buff.get_ref()[5..15], &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#[derive(Clone, Debug)] |
|
||||||
pub struct Cursor<T> { |
|
||||||
inner: T, |
|
||||||
pos: u64, |
|
||||||
} |
|
||||||
|
|
||||||
impl<T> Cursor<T> { |
|
||||||
/// Creates a new cursor wrapping the provided underlying in-memory buffer.
|
|
||||||
///
|
|
||||||
/// Cursor initial position is `0` even if underlying buffer (e.g. `Vec`)
|
|
||||||
/// is not empty. So writing to cursor starts with overwriting `Vec`
|
|
||||||
/// content, not with appending to it.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::io::Cursor;
|
|
||||||
///
|
|
||||||
/// let buff = Cursor::new(Vec::new());
|
|
||||||
/// # fn force_inference(_: &Cursor<Vec<u8>>) {}
|
|
||||||
/// # force_inference(&buff);
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub fn new(inner: T) -> Cursor<T> { |
|
||||||
Cursor { pos: 0, inner: inner } |
|
||||||
} |
|
||||||
|
|
||||||
/// Consumes this cursor, returning the underlying value.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::io::Cursor;
|
|
||||||
///
|
|
||||||
/// let buff = Cursor::new(Vec::new());
|
|
||||||
/// # fn force_inference(_: &Cursor<Vec<u8>>) {}
|
|
||||||
/// # force_inference(&buff);
|
|
||||||
///
|
|
||||||
/// let vec = buff.into_inner();
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub fn into_inner(self) -> T { self.inner } |
|
||||||
|
|
||||||
/// Gets a reference to the underlying value in this cursor.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::io::Cursor;
|
|
||||||
///
|
|
||||||
/// let buff = Cursor::new(Vec::new());
|
|
||||||
/// # fn force_inference(_: &Cursor<Vec<u8>>) {}
|
|
||||||
/// # force_inference(&buff);
|
|
||||||
///
|
|
||||||
/// let reference = buff.get_ref();
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub fn get_ref(&self) -> &T { &self.inner } |
|
||||||
|
|
||||||
/// Gets a mutable reference to the underlying value in this cursor.
|
|
||||||
///
|
|
||||||
/// Care should be taken to avoid modifying the internal I/O state of the
|
|
||||||
/// underlying value as it may corrupt this cursor's position.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::io::Cursor;
|
|
||||||
///
|
|
||||||
/// let mut buff = Cursor::new(Vec::new());
|
|
||||||
/// # fn force_inference(_: &Cursor<Vec<u8>>) {}
|
|
||||||
/// # force_inference(&buff);
|
|
||||||
///
|
|
||||||
/// let reference = buff.get_mut();
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub fn get_mut(&mut self) -> &mut T { &mut self.inner } |
|
||||||
|
|
||||||
/// Returns the current position of this cursor.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::io::Cursor;
|
|
||||||
/// use std::io::prelude::*;
|
|
||||||
/// use std::io::SeekFrom;
|
|
||||||
///
|
|
||||||
/// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
|
|
||||||
///
|
|
||||||
/// assert_eq!(buff.position(), 0);
|
|
||||||
///
|
|
||||||
/// buff.seek(SeekFrom::Current(2)).unwrap();
|
|
||||||
/// assert_eq!(buff.position(), 2);
|
|
||||||
///
|
|
||||||
/// buff.seek(SeekFrom::Current(-1)).unwrap();
|
|
||||||
/// assert_eq!(buff.position(), 1);
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub fn position(&self) -> u64 { self.pos } |
|
||||||
|
|
||||||
/// Sets the position of this cursor.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::io::Cursor;
|
|
||||||
///
|
|
||||||
/// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
|
|
||||||
///
|
|
||||||
/// assert_eq!(buff.position(), 0);
|
|
||||||
///
|
|
||||||
/// buff.set_position(2);
|
|
||||||
/// assert_eq!(buff.position(), 2);
|
|
||||||
///
|
|
||||||
/// buff.set_position(4);
|
|
||||||
/// assert_eq!(buff.position(), 4);
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub fn set_position(&mut self, pos: u64) { self.pos = pos; } |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl<T> io::Seek for Cursor<T> where T: AsRef<[u8]> { |
|
||||||
fn seek(&mut self, style: SeekFrom) -> io::Result<u64> { |
|
||||||
let (base_pos, offset) = match style { |
|
||||||
SeekFrom::Start(n) => { self.pos = n; return Ok(n); } |
|
||||||
SeekFrom::End(n) => (self.inner.as_ref().len() as u64, n), |
|
||||||
SeekFrom::Current(n) => (self.pos, n), |
|
||||||
}; |
|
||||||
let new_pos = if offset >= 0 { |
|
||||||
base_pos.checked_add(offset as u64) |
|
||||||
} else { |
|
||||||
base_pos.checked_sub((offset.wrapping_neg()) as u64) |
|
||||||
}; |
|
||||||
match new_pos { |
|
||||||
Some(n) => {self.pos = n; Ok(self.pos)} |
|
||||||
None => Err(Error::new(ErrorKind::InvalidInput, |
|
||||||
"invalid seek to a negative or overflowing position")) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl<T> Read for Cursor<T> where T: AsRef<[u8]> { |
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
|
||||||
let n = Read::read(&mut self.fill_buf()?, buf)?; |
|
||||||
self.pos += n as u64; |
|
||||||
Ok(n) |
|
||||||
} |
|
||||||
|
|
||||||
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { |
|
||||||
let n = buf.len(); |
|
||||||
Read::read_exact(&mut self.fill_buf()?, buf)?; |
|
||||||
self.pos += n as u64; |
|
||||||
Ok(()) |
|
||||||
} |
|
||||||
|
|
||||||
#[inline] |
|
||||||
unsafe fn initializer(&self) -> Initializer { |
|
||||||
Initializer::nop() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl<T> BufRead for Cursor<T> where T: AsRef<[u8]> { |
|
||||||
fn fill_buf(&mut self) -> io::Result<&[u8]> { |
|
||||||
let amt = cmp::min(self.pos, self.inner.as_ref().len() as u64); |
|
||||||
Ok(&self.inner.as_ref()[(amt as usize)..]) |
|
||||||
} |
|
||||||
fn consume(&mut self, amt: usize) { self.pos += amt as u64; } |
|
||||||
} |
|
||||||
|
|
||||||
// Non-resizing write implementation
|
|
||||||
fn slice_write(pos_mut: &mut u64, slice: &mut [u8], buf: &[u8]) -> io::Result<usize> { |
|
||||||
let pos = cmp::min(*pos_mut, slice.len() as u64); |
|
||||||
let amt = (&mut slice[(pos as usize)..]).write(buf)?; |
|
||||||
*pos_mut += amt as u64; |
|
||||||
Ok(amt) |
|
||||||
} |
|
||||||
|
|
||||||
// Resizing write implementation
|
|
||||||
fn vec_write(pos_mut: &mut u64, vec: &mut Vec<u8>, buf: &[u8]) -> io::Result<usize> { |
|
||||||
let pos: usize = (*pos_mut).try_into().map_err(|_| { |
|
||||||
Error::new(ErrorKind::InvalidInput, |
|
||||||
"cursor position exceeds maximum possible vector length") |
|
||||||
})?; |
|
||||||
// Make sure the internal buffer is as least as big as where we
|
|
||||||
// currently are
|
|
||||||
let len = vec.len(); |
|
||||||
if len < pos { |
|
||||||
// use `resize` so that the zero filling is as efficient as possible
|
|
||||||
vec.resize(pos, 0); |
|
||||||
} |
|
||||||
// Figure out what bytes will be used to overwrite what's currently
|
|
||||||
// there (left), and what will be appended on the end (right)
|
|
||||||
{ |
|
||||||
let space = vec.len() - pos; |
|
||||||
let (left, right) = buf.split_at(cmp::min(space, buf.len())); |
|
||||||
vec[pos..pos + left.len()].copy_from_slice(left); |
|
||||||
vec.extend_from_slice(right); |
|
||||||
} |
|
||||||
|
|
||||||
// Bump us forward
|
|
||||||
*pos_mut = (pos + buf.len()) as u64; |
|
||||||
Ok(buf.len()) |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl<'a> Write for Cursor<&'a mut [u8]> { |
|
||||||
#[inline] |
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
|
||||||
slice_write(&mut self.pos, self.inner, buf) |
|
||||||
} |
|
||||||
fn flush(&mut self) -> io::Result<()> { Ok(()) } |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "cursor_mut_vec", since = "1.25.0")] |
|
||||||
impl<'a> Write for Cursor<&'a mut Vec<u8>> { |
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
|
||||||
vec_write(&mut self.pos, self.inner, buf) |
|
||||||
} |
|
||||||
fn flush(&mut self) -> io::Result<()> { Ok(()) } |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl Write for Cursor<Vec<u8>> { |
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
|
||||||
vec_write(&mut self.pos, &mut self.inner, buf) |
|
||||||
} |
|
||||||
fn flush(&mut self) -> io::Result<()> { Ok(()) } |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "cursor_box_slice", since = "1.5.0")] |
|
||||||
impl Write for Cursor<Box<[u8]>> { |
|
||||||
#[inline] |
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
|
||||||
slice_write(&mut self.pos, &mut self.inner, buf) |
|
||||||
} |
|
||||||
fn flush(&mut self) -> io::Result<()> { Ok(()) } |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(test)] |
|
||||||
mod tests { |
|
||||||
use io::prelude::*; |
|
||||||
use io::{Cursor, SeekFrom}; |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_vec_writer() { |
|
||||||
let mut writer = Vec::new(); |
|
||||||
assert_eq!(writer.write(&[0]).unwrap(), 1); |
|
||||||
assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); |
|
||||||
assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); |
|
||||||
let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7]; |
|
||||||
assert_eq!(writer, b); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_mem_writer() { |
|
||||||
let mut writer = Cursor::new(Vec::new()); |
|
||||||
assert_eq!(writer.write(&[0]).unwrap(), 1); |
|
||||||
assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); |
|
||||||
assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); |
|
||||||
let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7]; |
|
||||||
assert_eq!(&writer.get_ref()[..], b); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_mem_mut_writer() { |
|
||||||
let mut vec = Vec::new(); |
|
||||||
let mut writer = Cursor::new(&mut vec); |
|
||||||
assert_eq!(writer.write(&[0]).unwrap(), 1); |
|
||||||
assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); |
|
||||||
assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); |
|
||||||
let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7]; |
|
||||||
assert_eq!(&writer.get_ref()[..], b); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_box_slice_writer() { |
|
||||||
let mut writer = Cursor::new(vec![0u8; 9].into_boxed_slice()); |
|
||||||
assert_eq!(writer.position(), 0); |
|
||||||
assert_eq!(writer.write(&[0]).unwrap(), 1); |
|
||||||
assert_eq!(writer.position(), 1); |
|
||||||
assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); |
|
||||||
assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); |
|
||||||
assert_eq!(writer.position(), 8); |
|
||||||
assert_eq!(writer.write(&[]).unwrap(), 0); |
|
||||||
assert_eq!(writer.position(), 8); |
|
||||||
|
|
||||||
assert_eq!(writer.write(&[8, 9]).unwrap(), 1); |
|
||||||
assert_eq!(writer.write(&[10]).unwrap(), 0); |
|
||||||
let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8]; |
|
||||||
assert_eq!(&**writer.get_ref(), b); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_buf_writer() { |
|
||||||
let mut buf = [0 as u8; 9]; |
|
||||||
{ |
|
||||||
let mut writer = Cursor::new(&mut buf[..]); |
|
||||||
assert_eq!(writer.position(), 0); |
|
||||||
assert_eq!(writer.write(&[0]).unwrap(), 1); |
|
||||||
assert_eq!(writer.position(), 1); |
|
||||||
assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); |
|
||||||
assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); |
|
||||||
assert_eq!(writer.position(), 8); |
|
||||||
assert_eq!(writer.write(&[]).unwrap(), 0); |
|
||||||
assert_eq!(writer.position(), 8); |
|
||||||
|
|
||||||
assert_eq!(writer.write(&[8, 9]).unwrap(), 1); |
|
||||||
assert_eq!(writer.write(&[10]).unwrap(), 0); |
|
||||||
} |
|
||||||
let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8]; |
|
||||||
assert_eq!(buf, b); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_buf_writer_seek() { |
|
||||||
let mut buf = [0 as u8; 8]; |
|
||||||
{ |
|
||||||
let mut writer = Cursor::new(&mut buf[..]); |
|
||||||
assert_eq!(writer.position(), 0); |
|
||||||
assert_eq!(writer.write(&[1]).unwrap(), 1); |
|
||||||
assert_eq!(writer.position(), 1); |
|
||||||
|
|
||||||
assert_eq!(writer.seek(SeekFrom::Start(2)).unwrap(), 2); |
|
||||||
assert_eq!(writer.position(), 2); |
|
||||||
assert_eq!(writer.write(&[2]).unwrap(), 1); |
|
||||||
assert_eq!(writer.position(), 3); |
|
||||||
|
|
||||||
assert_eq!(writer.seek(SeekFrom::Current(-2)).unwrap(), 1); |
|
||||||
assert_eq!(writer.position(), 1); |
|
||||||
assert_eq!(writer.write(&[3]).unwrap(), 1); |
|
||||||
assert_eq!(writer.position(), 2); |
|
||||||
|
|
||||||
assert_eq!(writer.seek(SeekFrom::End(-1)).unwrap(), 7); |
|
||||||
assert_eq!(writer.position(), 7); |
|
||||||
assert_eq!(writer.write(&[4]).unwrap(), 1); |
|
||||||
assert_eq!(writer.position(), 8); |
|
||||||
|
|
||||||
} |
|
||||||
let b: &[_] = &[1, 3, 2, 0, 0, 0, 0, 4]; |
|
||||||
assert_eq!(buf, b); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_buf_writer_error() { |
|
||||||
let mut buf = [0 as u8; 2]; |
|
||||||
let mut writer = Cursor::new(&mut buf[..]); |
|
||||||
assert_eq!(writer.write(&[0]).unwrap(), 1); |
|
||||||
assert_eq!(writer.write(&[0, 0]).unwrap(), 1); |
|
||||||
assert_eq!(writer.write(&[0, 0]).unwrap(), 0); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_mem_reader() { |
|
||||||
let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]); |
|
||||||
let mut buf = []; |
|
||||||
assert_eq!(reader.read(&mut buf).unwrap(), 0); |
|
||||||
assert_eq!(reader.position(), 0); |
|
||||||
let mut buf = [0]; |
|
||||||
assert_eq!(reader.read(&mut buf).unwrap(), 1); |
|
||||||
assert_eq!(reader.position(), 1); |
|
||||||
let b: &[_] = &[0]; |
|
||||||
assert_eq!(buf, b); |
|
||||||
let mut buf = [0; 4]; |
|
||||||
assert_eq!(reader.read(&mut buf).unwrap(), 4); |
|
||||||
assert_eq!(reader.position(), 5); |
|
||||||
let b: &[_] = &[1, 2, 3, 4]; |
|
||||||
assert_eq!(buf, b); |
|
||||||
assert_eq!(reader.read(&mut buf).unwrap(), 3); |
|
||||||
let b: &[_] = &[5, 6, 7]; |
|
||||||
assert_eq!(&buf[..3], b); |
|
||||||
assert_eq!(reader.read(&mut buf).unwrap(), 0); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_boxed_slice_reader() { |
|
||||||
let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7].into_boxed_slice()); |
|
||||||
let mut buf = []; |
|
||||||
assert_eq!(reader.read(&mut buf).unwrap(), 0); |
|
||||||
assert_eq!(reader.position(), 0); |
|
||||||
let mut buf = [0]; |
|
||||||
assert_eq!(reader.read(&mut buf).unwrap(), 1); |
|
||||||
assert_eq!(reader.position(), 1); |
|
||||||
let b: &[_] = &[0]; |
|
||||||
assert_eq!(buf, b); |
|
||||||
let mut buf = [0; 4]; |
|
||||||
assert_eq!(reader.read(&mut buf).unwrap(), 4); |
|
||||||
assert_eq!(reader.position(), 5); |
|
||||||
let b: &[_] = &[1, 2, 3, 4]; |
|
||||||
assert_eq!(buf, b); |
|
||||||
assert_eq!(reader.read(&mut buf).unwrap(), 3); |
|
||||||
let b: &[_] = &[5, 6, 7]; |
|
||||||
assert_eq!(&buf[..3], b); |
|
||||||
assert_eq!(reader.read(&mut buf).unwrap(), 0); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn read_to_end() { |
|
||||||
let mut reader = Cursor::new(vec![0, 1, 2, 3, 4, 5, 6, 7]); |
|
||||||
let mut v = Vec::new(); |
|
||||||
reader.read_to_end(&mut v).unwrap(); |
|
||||||
assert_eq!(v, [0, 1, 2, 3, 4, 5, 6, 7]); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_slice_reader() { |
|
||||||
let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7]; |
|
||||||
let reader = &mut &in_buf[..]; |
|
||||||
let mut buf = []; |
|
||||||
assert_eq!(reader.read(&mut buf).unwrap(), 0); |
|
||||||
let mut buf = [0]; |
|
||||||
assert_eq!(reader.read(&mut buf).unwrap(), 1); |
|
||||||
assert_eq!(reader.len(), 7); |
|
||||||
let b: &[_] = &[0]; |
|
||||||
assert_eq!(&buf[..], b); |
|
||||||
let mut buf = [0; 4]; |
|
||||||
assert_eq!(reader.read(&mut buf).unwrap(), 4); |
|
||||||
assert_eq!(reader.len(), 3); |
|
||||||
let b: &[_] = &[1, 2, 3, 4]; |
|
||||||
assert_eq!(&buf[..], b); |
|
||||||
assert_eq!(reader.read(&mut buf).unwrap(), 3); |
|
||||||
let b: &[_] = &[5, 6, 7]; |
|
||||||
assert_eq!(&buf[..3], b); |
|
||||||
assert_eq!(reader.read(&mut buf).unwrap(), 0); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_read_exact() { |
|
||||||
let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7]; |
|
||||||
let reader = &mut &in_buf[..]; |
|
||||||
let mut buf = []; |
|
||||||
assert!(reader.read_exact(&mut buf).is_ok()); |
|
||||||
let mut buf = [8]; |
|
||||||
assert!(reader.read_exact(&mut buf).is_ok()); |
|
||||||
assert_eq!(buf[0], 0); |
|
||||||
assert_eq!(reader.len(), 7); |
|
||||||
let mut buf = [0, 0, 0, 0, 0, 0, 0]; |
|
||||||
assert!(reader.read_exact(&mut buf).is_ok()); |
|
||||||
assert_eq!(buf, [1, 2, 3, 4, 5, 6, 7]); |
|
||||||
assert_eq!(reader.len(), 0); |
|
||||||
let mut buf = [0]; |
|
||||||
assert!(reader.read_exact(&mut buf).is_err()); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_buf_reader() { |
|
||||||
let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7]; |
|
||||||
let mut reader = Cursor::new(&in_buf[..]); |
|
||||||
let mut buf = []; |
|
||||||
assert_eq!(reader.read(&mut buf).unwrap(), 0); |
|
||||||
assert_eq!(reader.position(), 0); |
|
||||||
let mut buf = [0]; |
|
||||||
assert_eq!(reader.read(&mut buf).unwrap(), 1); |
|
||||||
assert_eq!(reader.position(), 1); |
|
||||||
let b: &[_] = &[0]; |
|
||||||
assert_eq!(buf, b); |
|
||||||
let mut buf = [0; 4]; |
|
||||||
assert_eq!(reader.read(&mut buf).unwrap(), 4); |
|
||||||
assert_eq!(reader.position(), 5); |
|
||||||
let b: &[_] = &[1, 2, 3, 4]; |
|
||||||
assert_eq!(buf, b); |
|
||||||
assert_eq!(reader.read(&mut buf).unwrap(), 3); |
|
||||||
let b: &[_] = &[5, 6, 7]; |
|
||||||
assert_eq!(&buf[..3], b); |
|
||||||
assert_eq!(reader.read(&mut buf).unwrap(), 0); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn seek_past_end() { |
|
||||||
let buf = [0xff]; |
|
||||||
let mut r = Cursor::new(&buf[..]); |
|
||||||
assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); |
|
||||||
assert_eq!(r.read(&mut [0]).unwrap(), 0); |
|
||||||
|
|
||||||
let mut r = Cursor::new(vec![10]); |
|
||||||
assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); |
|
||||||
assert_eq!(r.read(&mut [0]).unwrap(), 0); |
|
||||||
|
|
||||||
let mut buf = [0]; |
|
||||||
let mut r = Cursor::new(&mut buf[..]); |
|
||||||
assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); |
|
||||||
assert_eq!(r.write(&[3]).unwrap(), 0); |
|
||||||
|
|
||||||
let mut r = Cursor::new(vec![10].into_boxed_slice()); |
|
||||||
assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); |
|
||||||
assert_eq!(r.write(&[3]).unwrap(), 0); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn seek_past_i64() { |
|
||||||
let buf = [0xff]; |
|
||||||
let mut r = Cursor::new(&buf[..]); |
|
||||||
assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); |
|
||||||
assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); |
|
||||||
assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); |
|
||||||
assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); |
|
||||||
assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); |
|
||||||
assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); |
|
||||||
|
|
||||||
let mut r = Cursor::new(vec![10]); |
|
||||||
assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); |
|
||||||
assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); |
|
||||||
assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); |
|
||||||
assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); |
|
||||||
assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); |
|
||||||
assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); |
|
||||||
|
|
||||||
let mut buf = [0]; |
|
||||||
let mut r = Cursor::new(&mut buf[..]); |
|
||||||
assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); |
|
||||||
assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); |
|
||||||
assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); |
|
||||||
assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); |
|
||||||
assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); |
|
||||||
assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); |
|
||||||
|
|
||||||
let mut r = Cursor::new(vec![10].into_boxed_slice()); |
|
||||||
assert_eq!(r.seek(SeekFrom::Start(6)).unwrap(), 6); |
|
||||||
assert_eq!(r.seek(SeekFrom::Current(0x7ffffffffffffff0)).unwrap(), 0x7ffffffffffffff6); |
|
||||||
assert_eq!(r.seek(SeekFrom::Current(0x10)).unwrap(), 0x8000000000000006); |
|
||||||
assert_eq!(r.seek(SeekFrom::Current(0)).unwrap(), 0x8000000000000006); |
|
||||||
assert!(r.seek(SeekFrom::Current(0x7ffffffffffffffd)).is_err()); |
|
||||||
assert_eq!(r.seek(SeekFrom::Current(-0x8000000000000000)).unwrap(), 6); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn seek_before_0() { |
|
||||||
let buf = [0xff]; |
|
||||||
let mut r = Cursor::new(&buf[..]); |
|
||||||
assert!(r.seek(SeekFrom::End(-2)).is_err()); |
|
||||||
|
|
||||||
let mut r = Cursor::new(vec![10]); |
|
||||||
assert!(r.seek(SeekFrom::End(-2)).is_err()); |
|
||||||
|
|
||||||
let mut buf = [0]; |
|
||||||
let mut r = Cursor::new(&mut buf[..]); |
|
||||||
assert!(r.seek(SeekFrom::End(-2)).is_err()); |
|
||||||
|
|
||||||
let mut r = Cursor::new(vec![10].into_boxed_slice()); |
|
||||||
assert!(r.seek(SeekFrom::End(-2)).is_err()); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_seekable_mem_writer() { |
|
||||||
let mut writer = Cursor::new(Vec::<u8>::new()); |
|
||||||
assert_eq!(writer.position(), 0); |
|
||||||
assert_eq!(writer.write(&[0]).unwrap(), 1); |
|
||||||
assert_eq!(writer.position(), 1); |
|
||||||
assert_eq!(writer.write(&[1, 2, 3]).unwrap(), 3); |
|
||||||
assert_eq!(writer.write(&[4, 5, 6, 7]).unwrap(), 4); |
|
||||||
assert_eq!(writer.position(), 8); |
|
||||||
let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7]; |
|
||||||
assert_eq!(&writer.get_ref()[..], b); |
|
||||||
|
|
||||||
assert_eq!(writer.seek(SeekFrom::Start(0)).unwrap(), 0); |
|
||||||
assert_eq!(writer.position(), 0); |
|
||||||
assert_eq!(writer.write(&[3, 4]).unwrap(), 2); |
|
||||||
let b: &[_] = &[3, 4, 2, 3, 4, 5, 6, 7]; |
|
||||||
assert_eq!(&writer.get_ref()[..], b); |
|
||||||
|
|
||||||
assert_eq!(writer.seek(SeekFrom::Current(1)).unwrap(), 3); |
|
||||||
assert_eq!(writer.write(&[0, 1]).unwrap(), 2); |
|
||||||
let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 7]; |
|
||||||
assert_eq!(&writer.get_ref()[..], b); |
|
||||||
|
|
||||||
assert_eq!(writer.seek(SeekFrom::End(-1)).unwrap(), 7); |
|
||||||
assert_eq!(writer.write(&[1, 2]).unwrap(), 2); |
|
||||||
let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2]; |
|
||||||
assert_eq!(&writer.get_ref()[..], b); |
|
||||||
|
|
||||||
assert_eq!(writer.seek(SeekFrom::End(1)).unwrap(), 10); |
|
||||||
assert_eq!(writer.write(&[1]).unwrap(), 1); |
|
||||||
let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2, 0, 1]; |
|
||||||
assert_eq!(&writer.get_ref()[..], b); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn vec_seek_past_end() { |
|
||||||
let mut r = Cursor::new(Vec::new()); |
|
||||||
assert_eq!(r.seek(SeekFrom::Start(10)).unwrap(), 10); |
|
||||||
assert_eq!(r.write(&[3]).unwrap(), 1); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn vec_seek_before_0() { |
|
||||||
let mut r = Cursor::new(Vec::new()); |
|
||||||
assert!(r.seek(SeekFrom::End(-2)).is_err()); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
#[cfg(target_pointer_width = "32")] |
|
||||||
fn vec_seek_and_write_past_usize_max() { |
|
||||||
let mut c = Cursor::new(Vec::new()); |
|
||||||
c.set_position(<usize>::max_value() as u64 + 1); |
|
||||||
assert!(c.write_all(&[1, 2, 3]).is_err()); |
|
||||||
} |
|
||||||
} |
|
@ -1,620 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
use error; |
|
||||||
use fmt; |
|
||||||
use result; |
|
||||||
use sys; |
|
||||||
use convert::From; |
|
||||||
|
|
||||||
/// A specialized [`Result`](../result/enum.Result.html) type for I/O
|
|
||||||
/// operations.
|
|
||||||
///
|
|
||||||
/// This type is broadly used across [`std::io`] for any operation which may
|
|
||||||
/// produce an error.
|
|
||||||
///
|
|
||||||
/// This typedef is generally used to avoid writing out [`io::Error`] directly and
|
|
||||||
/// is otherwise a direct mapping to [`Result`].
|
|
||||||
///
|
|
||||||
/// While usual Rust style is to import types directly, aliases of [`Result`]
|
|
||||||
/// often are not, to make it easier to distinguish between them. [`Result`] is
|
|
||||||
/// generally assumed to be [`std::result::Result`][`Result`], and so users of this alias
|
|
||||||
/// will generally use `io::Result` instead of shadowing the prelude's import
|
|
||||||
/// of [`std::result::Result`][`Result`].
|
|
||||||
///
|
|
||||||
/// [`std::io`]: ../io/index.html
|
|
||||||
/// [`io::Error`]: ../io/struct.Error.html
|
|
||||||
/// [`Result`]: ../result/enum.Result.html
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// A convenience function that bubbles an `io::Result` to its caller:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::io;
|
|
||||||
///
|
|
||||||
/// fn get_string() -> io::Result<String> {
|
|
||||||
/// let mut buffer = String::new();
|
|
||||||
///
|
|
||||||
/// io::stdin().read_line(&mut buffer)?;
|
|
||||||
///
|
|
||||||
/// Ok(buffer)
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub type Result<T> = result::Result<T, Error>; |
|
||||||
|
|
||||||
/// The error type for I/O operations of the [`Read`], [`Write`], [`Seek`], and
|
|
||||||
/// associated traits.
|
|
||||||
///
|
|
||||||
/// Errors mostly originate from the underlying OS, but custom instances of
|
|
||||||
/// `Error` can be created with crafted error messages and a particular value of
|
|
||||||
/// [`ErrorKind`].
|
|
||||||
///
|
|
||||||
/// [`Read`]: ../io/trait.Read.html
|
|
||||||
/// [`Write`]: ../io/trait.Write.html
|
|
||||||
/// [`Seek`]: ../io/trait.Seek.html
|
|
||||||
/// [`ErrorKind`]: enum.ErrorKind.html
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub struct Error { |
|
||||||
repr: Repr, |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl fmt::Debug for Error { |
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
|
||||||
fmt::Debug::fmt(&self.repr, f) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
enum Repr { |
|
||||||
Os(i32), |
|
||||||
Simple(ErrorKind), |
|
||||||
Custom(Box<Custom>), |
|
||||||
} |
|
||||||
|
|
||||||
#[derive(Debug)] |
|
||||||
struct Custom { |
|
||||||
kind: ErrorKind, |
|
||||||
error: Box<dyn error::Error+Send+Sync>, |
|
||||||
} |
|
||||||
|
|
||||||
/// A list specifying general categories of I/O error.
|
|
||||||
///
|
|
||||||
/// This list is intended to grow over time and it is not recommended to
|
|
||||||
/// exhaustively match against it.
|
|
||||||
///
|
|
||||||
/// It is used with the [`io::Error`] type.
|
|
||||||
///
|
|
||||||
/// [`io::Error`]: struct.Error.html
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#[allow(deprecated)] |
|
||||||
#[non_exhaustive] |
|
||||||
pub enum ErrorKind { |
|
||||||
/// An entity was not found, often a file.
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
NotFound, |
|
||||||
/// The operation lacked the necessary privileges to complete.
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
PermissionDenied, |
|
||||||
/// The connection was refused by the remote server.
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
ConnectionRefused, |
|
||||||
/// The connection was reset by the remote server.
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
ConnectionReset, |
|
||||||
/// The connection was aborted (terminated) by the remote server.
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
ConnectionAborted, |
|
||||||
/// The network operation failed because it was not connected yet.
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
NotConnected, |
|
||||||
/// A socket address could not be bound because the address is already in
|
|
||||||
/// use elsewhere.
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
AddrInUse, |
|
||||||
/// A nonexistent interface was requested or the requested address was not
|
|
||||||
/// local.
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
AddrNotAvailable, |
|
||||||
/// The operation failed because a pipe was closed.
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
BrokenPipe, |
|
||||||
/// An entity already exists, often a file.
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
AlreadyExists, |
|
||||||
/// The operation needs to block to complete, but the blocking operation was
|
|
||||||
/// requested to not occur.
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
WouldBlock, |
|
||||||
/// A parameter was incorrect.
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
InvalidInput, |
|
||||||
/// Data not valid for the operation were encountered.
|
|
||||||
///
|
|
||||||
/// Unlike [`InvalidInput`], this typically means that the operation
|
|
||||||
/// parameters were valid, however the error was caused by malformed
|
|
||||||
/// input data.
|
|
||||||
///
|
|
||||||
/// For example, a function that reads a file into a string will error with
|
|
||||||
/// `InvalidData` if the file's contents are not valid UTF-8.
|
|
||||||
///
|
|
||||||
/// [`InvalidInput`]: #variant.InvalidInput
|
|
||||||
#[stable(feature = "io_invalid_data", since = "1.2.0")] |
|
||||||
InvalidData, |
|
||||||
/// The I/O operation's timeout expired, causing it to be canceled.
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
TimedOut, |
|
||||||
/// An error returned when an operation could not be completed because a
|
|
||||||
/// call to [`write`] returned [`Ok(0)`].
|
|
||||||
///
|
|
||||||
/// This typically means that an operation could only succeed if it wrote a
|
|
||||||
/// particular number of bytes but only a smaller number of bytes could be
|
|
||||||
/// written.
|
|
||||||
///
|
|
||||||
/// [`write`]: ../../std/io/trait.Write.html#tymethod.write
|
|
||||||
/// [`Ok(0)`]: ../../std/io/type.Result.html
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
WriteZero, |
|
||||||
/// This operation was interrupted.
|
|
||||||
///
|
|
||||||
/// Interrupted operations can typically be retried.
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
Interrupted, |
|
||||||
/// Any I/O error not part of this list.
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
Other, |
|
||||||
|
|
||||||
/// An error returned when an operation could not be completed because an
|
|
||||||
/// "end of file" was reached prematurely.
|
|
||||||
///
|
|
||||||
/// This typically means that an operation could only succeed if it read a
|
|
||||||
/// particular number of bytes but only a smaller number of bytes could be
|
|
||||||
/// read.
|
|
||||||
#[stable(feature = "read_exact", since = "1.6.0")] |
|
||||||
UnexpectedEof, |
|
||||||
} |
|
||||||
|
|
||||||
impl ErrorKind { |
|
||||||
fn as_str(&self) -> &'static str { |
|
||||||
match *self { |
|
||||||
ErrorKind::NotFound => "entity not found", |
|
||||||
ErrorKind::PermissionDenied => "permission denied", |
|
||||||
ErrorKind::ConnectionRefused => "connection refused", |
|
||||||
ErrorKind::ConnectionReset => "connection reset", |
|
||||||
ErrorKind::ConnectionAborted => "connection aborted", |
|
||||||
ErrorKind::NotConnected => "not connected", |
|
||||||
ErrorKind::AddrInUse => "address in use", |
|
||||||
ErrorKind::AddrNotAvailable => "address not available", |
|
||||||
ErrorKind::BrokenPipe => "broken pipe", |
|
||||||
ErrorKind::AlreadyExists => "entity already exists", |
|
||||||
ErrorKind::WouldBlock => "operation would block", |
|
||||||
ErrorKind::InvalidInput => "invalid input parameter", |
|
||||||
ErrorKind::InvalidData => "invalid data", |
|
||||||
ErrorKind::TimedOut => "timed out", |
|
||||||
ErrorKind::WriteZero => "write zero", |
|
||||||
ErrorKind::Interrupted => "operation interrupted", |
|
||||||
ErrorKind::Other => "other os error", |
|
||||||
ErrorKind::UnexpectedEof => "unexpected end of file", |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// Intended for use for errors not exposed to the user, where allocating onto
|
|
||||||
/// the heap (for normal construction via Error::new) is too costly.
|
|
||||||
#[stable(feature = "io_error_from_errorkind", since = "1.14.0")] |
|
||||||
impl From<ErrorKind> for Error { |
|
||||||
#[inline] |
|
||||||
fn from(kind: ErrorKind) -> Error { |
|
||||||
Error { |
|
||||||
repr: Repr::Simple(kind) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl Error { |
|
||||||
/// Creates a new I/O error from a known kind of error as well as an
|
|
||||||
/// arbitrary error payload.
|
|
||||||
///
|
|
||||||
/// This function is used to generically create I/O errors which do not
|
|
||||||
/// originate from the OS itself. The `error` argument is an arbitrary
|
|
||||||
/// payload which will be contained in this `Error`.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::io::{Error, ErrorKind};
|
|
||||||
///
|
|
||||||
/// // errors can be created from strings
|
|
||||||
/// let custom_error = Error::new(ErrorKind::Other, "oh no!");
|
|
||||||
///
|
|
||||||
/// // errors can also be created from other errors
|
|
||||||
/// let custom_error2 = Error::new(ErrorKind::Interrupted, custom_error);
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub fn new<E>(kind: ErrorKind, error: E) -> Error |
|
||||||
where E: Into<Box<dyn error::Error+Send+Sync>> |
|
||||||
{ |
|
||||||
Self::_new(kind, error.into()) |
|
||||||
} |
|
||||||
|
|
||||||
fn _new(kind: ErrorKind, error: Box<dyn error::Error+Send+Sync>) -> Error { |
|
||||||
Error { |
|
||||||
repr: Repr::Custom(Box::new(Custom { |
|
||||||
kind, |
|
||||||
error, |
|
||||||
})) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// Returns an error representing the last OS error which occurred.
|
|
||||||
///
|
|
||||||
/// This function reads the value of `errno` for the target platform (e.g.
|
|
||||||
/// `GetLastError` on Windows) and will return a corresponding instance of
|
|
||||||
/// `Error` for the error code.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::io::Error;
|
|
||||||
///
|
|
||||||
/// println!("last OS error: {:?}", Error::last_os_error());
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub fn last_os_error() -> Error { |
|
||||||
Error::from_raw_os_error(sys::os::errno() as i32) |
|
||||||
} |
|
||||||
|
|
||||||
/// Creates a new instance of an `Error` from a particular OS error code.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// On Linux:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// # if cfg!(target_os = "linux") {
|
|
||||||
/// use std::io;
|
|
||||||
///
|
|
||||||
/// let error = io::Error::from_raw_os_error(22);
|
|
||||||
/// assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// On Windows:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// # if cfg!(windows) {
|
|
||||||
/// use std::io;
|
|
||||||
///
|
|
||||||
/// let error = io::Error::from_raw_os_error(10022);
|
|
||||||
/// assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub fn from_raw_os_error(code: i32) -> Error { |
|
||||||
Error { repr: Repr::Os(code) } |
|
||||||
} |
|
||||||
|
|
||||||
/// Returns the OS error that this error represents (if any).
|
|
||||||
///
|
|
||||||
/// If this `Error` was constructed via `last_os_error` or
|
|
||||||
/// `from_raw_os_error`, then this function will return `Some`, otherwise
|
|
||||||
/// it will return `None`.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::io::{Error, ErrorKind};
|
|
||||||
///
|
|
||||||
/// fn print_os_error(err: &Error) {
|
|
||||||
/// if let Some(raw_os_err) = err.raw_os_error() {
|
|
||||||
/// println!("raw OS error: {:?}", raw_os_err);
|
|
||||||
/// } else {
|
|
||||||
/// println!("Not an OS error");
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// fn main() {
|
|
||||||
/// // Will print "raw OS error: ...".
|
|
||||||
/// print_os_error(&Error::last_os_error());
|
|
||||||
/// // Will print "Not an OS error".
|
|
||||||
/// print_os_error(&Error::new(ErrorKind::Other, "oh no!"));
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub fn raw_os_error(&self) -> Option<i32> { |
|
||||||
match self.repr { |
|
||||||
Repr::Os(i) => Some(i), |
|
||||||
Repr::Custom(..) => None, |
|
||||||
Repr::Simple(..) => None, |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// Returns a reference to the inner error wrapped by this error (if any).
|
|
||||||
///
|
|
||||||
/// If this `Error` was constructed via `new` then this function will
|
|
||||||
/// return `Some`, otherwise it will return `None`.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::io::{Error, ErrorKind};
|
|
||||||
///
|
|
||||||
/// fn print_error(err: &Error) {
|
|
||||||
/// if let Some(inner_err) = err.get_ref() {
|
|
||||||
/// println!("Inner error: {:?}", inner_err);
|
|
||||||
/// } else {
|
|
||||||
/// println!("No inner error");
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// fn main() {
|
|
||||||
/// // Will print "No inner error".
|
|
||||||
/// print_error(&Error::last_os_error());
|
|
||||||
/// // Will print "Inner error: ...".
|
|
||||||
/// print_error(&Error::new(ErrorKind::Other, "oh no!"));
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "io_error_inner", since = "1.3.0")] |
|
||||||
pub fn get_ref(&self) -> Option<&(dyn error::Error+Send+Sync+'static)> { |
|
||||||
match self.repr { |
|
||||||
Repr::Os(..) => None, |
|
||||||
Repr::Simple(..) => None, |
|
||||||
Repr::Custom(ref c) => Some(&*c.error), |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// Returns a mutable reference to the inner error wrapped by this error
|
|
||||||
/// (if any).
|
|
||||||
///
|
|
||||||
/// If this `Error` was constructed via `new` then this function will
|
|
||||||
/// return `Some`, otherwise it will return `None`.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::io::{Error, ErrorKind};
|
|
||||||
/// use std::{error, fmt};
|
|
||||||
/// use std::fmt::Display;
|
|
||||||
///
|
|
||||||
/// #[derive(Debug)]
|
|
||||||
/// struct MyError {
|
|
||||||
/// v: String,
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// impl MyError {
|
|
||||||
/// fn new() -> MyError {
|
|
||||||
/// MyError {
|
|
||||||
/// v: "oh no!".to_string()
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// fn change_message(&mut self, new_message: &str) {
|
|
||||||
/// self.v = new_message.to_string();
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// impl error::Error for MyError {
|
|
||||||
/// fn description(&self) -> &str { &self.v }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// impl Display for MyError {
|
|
||||||
/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
/// write!(f, "MyError: {}", &self.v)
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// fn change_error(mut err: Error) -> Error {
|
|
||||||
/// if let Some(inner_err) = err.get_mut() {
|
|
||||||
/// inner_err.downcast_mut::<MyError>().unwrap().change_message("I've been changed!");
|
|
||||||
/// }
|
|
||||||
/// err
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// fn print_error(err: &Error) {
|
|
||||||
/// if let Some(inner_err) = err.get_ref() {
|
|
||||||
/// println!("Inner error: {}", inner_err);
|
|
||||||
/// } else {
|
|
||||||
/// println!("No inner error");
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// fn main() {
|
|
||||||
/// // Will print "No inner error".
|
|
||||||
/// print_error(&change_error(Error::last_os_error()));
|
|
||||||
/// // Will print "Inner error: ...".
|
|
||||||
/// print_error(&change_error(Error::new(ErrorKind::Other, MyError::new())));
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "io_error_inner", since = "1.3.0")] |
|
||||||
pub fn get_mut(&mut self) -> Option<&mut (dyn error::Error+Send+Sync+'static)> { |
|
||||||
match self.repr { |
|
||||||
Repr::Os(..) => None, |
|
||||||
Repr::Simple(..) => None, |
|
||||||
Repr::Custom(ref mut c) => Some(&mut *c.error), |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// Consumes the `Error`, returning its inner error (if any).
|
|
||||||
///
|
|
||||||
/// If this `Error` was constructed via `new` then this function will
|
|
||||||
/// return `Some`, otherwise it will return `None`.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::io::{Error, ErrorKind};
|
|
||||||
///
|
|
||||||
/// fn print_error(err: Error) {
|
|
||||||
/// if let Some(inner_err) = err.into_inner() {
|
|
||||||
/// println!("Inner error: {}", inner_err);
|
|
||||||
/// } else {
|
|
||||||
/// println!("No inner error");
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// fn main() {
|
|
||||||
/// // Will print "No inner error".
|
|
||||||
/// print_error(Error::last_os_error());
|
|
||||||
/// // Will print "Inner error: ...".
|
|
||||||
/// print_error(Error::new(ErrorKind::Other, "oh no!"));
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "io_error_inner", since = "1.3.0")] |
|
||||||
pub fn into_inner(self) -> Option<Box<dyn error::Error+Send+Sync>> { |
|
||||||
match self.repr { |
|
||||||
Repr::Os(..) => None, |
|
||||||
Repr::Simple(..) => None, |
|
||||||
Repr::Custom(c) => Some(c.error) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// Returns the corresponding `ErrorKind` for this error.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::io::{Error, ErrorKind};
|
|
||||||
///
|
|
||||||
/// fn print_error(err: Error) {
|
|
||||||
/// println!("{:?}", err.kind());
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// fn main() {
|
|
||||||
/// // Will print "No inner error".
|
|
||||||
/// print_error(Error::last_os_error());
|
|
||||||
/// // Will print "Inner error: ...".
|
|
||||||
/// print_error(Error::new(ErrorKind::AddrInUse, "oh no!"));
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub fn kind(&self) -> ErrorKind { |
|
||||||
match self.repr { |
|
||||||
Repr::Os(code) => sys::decode_error_kind(code), |
|
||||||
Repr::Custom(ref c) => c.kind, |
|
||||||
Repr::Simple(kind) => kind, |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl fmt::Debug for Repr { |
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
|
||||||
match *self { |
|
||||||
Repr::Os(code) => |
|
||||||
fmt.debug_struct("Os") |
|
||||||
.field("code", &code) |
|
||||||
.field("kind", &sys::decode_error_kind(code)) |
|
||||||
.field("message", &sys::os::error_string(code)).finish(), |
|
||||||
Repr::Custom(ref c) => fmt::Debug::fmt(&c, fmt), |
|
||||||
Repr::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(), |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl fmt::Display for Error { |
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
|
||||||
match self.repr { |
|
||||||
Repr::Os(code) => { |
|
||||||
let detail = sys::os::error_string(code); |
|
||||||
write!(fmt, "{} (os error {})", detail, code) |
|
||||||
} |
|
||||||
Repr::Custom(ref c) => c.error.fmt(fmt), |
|
||||||
Repr::Simple(kind) => write!(fmt, "{}", kind.as_str()), |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl error::Error for Error { |
|
||||||
fn description(&self) -> &str { |
|
||||||
match self.repr { |
|
||||||
Repr::Os(..) | Repr::Simple(..) => self.kind().as_str(), |
|
||||||
Repr::Custom(ref c) => c.error.description(), |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fn cause(&self) -> Option<&dyn error::Error> { |
|
||||||
match self.repr { |
|
||||||
Repr::Os(..) => None, |
|
||||||
Repr::Simple(..) => None, |
|
||||||
Repr::Custom(ref c) => c.error.cause(), |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fn _assert_error_is_sync_send() { |
|
||||||
fn _is_sync_send<T: Sync+Send>() {} |
|
||||||
_is_sync_send::<Error>(); |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(test)] |
|
||||||
mod test { |
|
||||||
use super::{Error, ErrorKind, Repr, Custom}; |
|
||||||
use error; |
|
||||||
use fmt; |
|
||||||
use sys::os::error_string; |
|
||||||
use sys::decode_error_kind; |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_debug_error() { |
|
||||||
let code = 6; |
|
||||||
let msg = error_string(code); |
|
||||||
let kind = decode_error_kind(code); |
|
||||||
let err = Error { |
|
||||||
repr: Repr::Custom(box Custom { |
|
||||||
kind: ErrorKind::InvalidInput, |
|
||||||
error: box Error { |
|
||||||
repr: super::Repr::Os(code) |
|
||||||
}, |
|
||||||
}) |
|
||||||
}; |
|
||||||
let expected = format!( |
|
||||||
"Custom {{ \ |
|
||||||
kind: InvalidInput, \ |
|
||||||
error: Os {{ \ |
|
||||||
code: {:?}, \ |
|
||||||
kind: {:?}, \ |
|
||||||
message: {:?} \ |
|
||||||
}} \ |
|
||||||
}}", |
|
||||||
code, kind, msg |
|
||||||
); |
|
||||||
assert_eq!(format!("{:?}", err), expected); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_downcasting() { |
|
||||||
#[derive(Debug)] |
|
||||||
struct TestError; |
|
||||||
|
|
||||||
impl fmt::Display for TestError { |
|
||||||
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { |
|
||||||
Ok(()) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl error::Error for TestError { |
|
||||||
fn description(&self) -> &str { |
|
||||||
"asdf" |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// we have to call all of these UFCS style right now since method
|
|
||||||
// resolution won't implicitly drop the Send+Sync bounds
|
|
||||||
let mut err = Error::new(ErrorKind::Other, TestError); |
|
||||||
assert!(err.get_ref().unwrap().is::<TestError>()); |
|
||||||
assert_eq!("asdf", err.get_ref().unwrap().description()); |
|
||||||
assert!(err.get_mut().unwrap().is::<TestError>()); |
|
||||||
let extracted = err.into_inner().unwrap(); |
|
||||||
extracted.downcast::<TestError>().unwrap(); |
|
||||||
} |
|
||||||
} |
|
@ -1,337 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
use cmp; |
|
||||||
use io::{self, SeekFrom, Read, Initializer, Write, Seek, BufRead, Error, ErrorKind}; |
|
||||||
use fmt; |
|
||||||
use mem; |
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
// Forwarding implementations
|
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl<'a, R: Read + ?Sized> Read for &'a mut R { |
|
||||||
#[inline] |
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
|
||||||
(**self).read(buf) |
|
||||||
} |
|
||||||
|
|
||||||
#[inline] |
|
||||||
unsafe fn initializer(&self) -> Initializer { |
|
||||||
(**self).initializer() |
|
||||||
} |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> { |
|
||||||
(**self).read_to_end(buf) |
|
||||||
} |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> { |
|
||||||
(**self).read_to_string(buf) |
|
||||||
} |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { |
|
||||||
(**self).read_exact(buf) |
|
||||||
} |
|
||||||
} |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl<'a, W: Write + ?Sized> Write for &'a mut W { |
|
||||||
#[inline] |
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) } |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn flush(&mut self) -> io::Result<()> { (**self).flush() } |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { |
|
||||||
(**self).write_all(buf) |
|
||||||
} |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> { |
|
||||||
(**self).write_fmt(fmt) |
|
||||||
} |
|
||||||
} |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl<'a, S: Seek + ?Sized> Seek for &'a mut S { |
|
||||||
#[inline] |
|
||||||
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) } |
|
||||||
} |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl<'a, B: BufRead + ?Sized> BufRead for &'a mut B { |
|
||||||
#[inline] |
|
||||||
fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() } |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn consume(&mut self, amt: usize) { (**self).consume(amt) } |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> { |
|
||||||
(**self).read_until(byte, buf) |
|
||||||
} |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn read_line(&mut self, buf: &mut String) -> io::Result<usize> { |
|
||||||
(**self).read_line(buf) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl<R: Read + ?Sized> Read for Box<R> { |
|
||||||
#[inline] |
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
|
||||||
(**self).read(buf) |
|
||||||
} |
|
||||||
|
|
||||||
#[inline] |
|
||||||
unsafe fn initializer(&self) -> Initializer { |
|
||||||
(**self).initializer() |
|
||||||
} |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> { |
|
||||||
(**self).read_to_end(buf) |
|
||||||
} |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> { |
|
||||||
(**self).read_to_string(buf) |
|
||||||
} |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { |
|
||||||
(**self).read_exact(buf) |
|
||||||
} |
|
||||||
} |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl<W: Write + ?Sized> Write for Box<W> { |
|
||||||
#[inline] |
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) } |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn flush(&mut self) -> io::Result<()> { (**self).flush() } |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { |
|
||||||
(**self).write_all(buf) |
|
||||||
} |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> { |
|
||||||
(**self).write_fmt(fmt) |
|
||||||
} |
|
||||||
} |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl<S: Seek + ?Sized> Seek for Box<S> { |
|
||||||
#[inline] |
|
||||||
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) } |
|
||||||
} |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl<B: BufRead + ?Sized> BufRead for Box<B> { |
|
||||||
#[inline] |
|
||||||
fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() } |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn consume(&mut self, amt: usize) { (**self).consume(amt) } |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> { |
|
||||||
(**self).read_until(byte, buf) |
|
||||||
} |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn read_line(&mut self, buf: &mut String) -> io::Result<usize> { |
|
||||||
(**self).read_line(buf) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
// In-memory buffer implementations
|
|
||||||
|
|
||||||
/// Read is implemented for `&[u8]` by copying from the slice.
|
|
||||||
///
|
|
||||||
/// Note that reading updates the slice to point to the yet unread part.
|
|
||||||
/// The slice will be empty when EOF is reached.
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl<'a> Read for &'a [u8] { |
|
||||||
#[inline] |
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
|
||||||
let amt = cmp::min(buf.len(), self.len()); |
|
||||||
let (a, b) = self.split_at(amt); |
|
||||||
|
|
||||||
// First check if the amount of bytes we want to read is small:
|
|
||||||
// `copy_from_slice` will generally expand to a call to `memcpy`, and
|
|
||||||
// for a single byte the overhead is significant.
|
|
||||||
if amt == 1 { |
|
||||||
buf[0] = a[0]; |
|
||||||
} else { |
|
||||||
buf[..amt].copy_from_slice(a); |
|
||||||
} |
|
||||||
|
|
||||||
*self = b; |
|
||||||
Ok(amt) |
|
||||||
} |
|
||||||
|
|
||||||
#[inline] |
|
||||||
unsafe fn initializer(&self) -> Initializer { |
|
||||||
Initializer::nop() |
|
||||||
} |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { |
|
||||||
if buf.len() > self.len() { |
|
||||||
return Err(Error::new(ErrorKind::UnexpectedEof, |
|
||||||
"failed to fill whole buffer")); |
|
||||||
} |
|
||||||
let (a, b) = self.split_at(buf.len()); |
|
||||||
|
|
||||||
// First check if the amount of bytes we want to read is small:
|
|
||||||
// `copy_from_slice` will generally expand to a call to `memcpy`, and
|
|
||||||
// for a single byte the overhead is significant.
|
|
||||||
if buf.len() == 1 { |
|
||||||
buf[0] = a[0]; |
|
||||||
} else { |
|
||||||
buf.copy_from_slice(a); |
|
||||||
} |
|
||||||
|
|
||||||
*self = b; |
|
||||||
Ok(()) |
|
||||||
} |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> { |
|
||||||
buf.extend_from_slice(*self); |
|
||||||
let len = self.len(); |
|
||||||
*self = &self[len..]; |
|
||||||
Ok(len) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl<'a> BufRead for &'a [u8] { |
|
||||||
#[inline] |
|
||||||
fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(*self) } |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn consume(&mut self, amt: usize) { *self = &self[amt..]; } |
|
||||||
} |
|
||||||
|
|
||||||
/// Write is implemented for `&mut [u8]` by copying into the slice, overwriting
|
|
||||||
/// its data.
|
|
||||||
///
|
|
||||||
/// Note that writing updates the slice to point to the yet unwritten part.
|
|
||||||
/// The slice will be empty when it has been completely overwritten.
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl<'a> Write for &'a mut [u8] { |
|
||||||
#[inline] |
|
||||||
fn write(&mut self, data: &[u8]) -> io::Result<usize> { |
|
||||||
let amt = cmp::min(data.len(), self.len()); |
|
||||||
let (a, b) = mem::replace(self, &mut []).split_at_mut(amt); |
|
||||||
a.copy_from_slice(&data[..amt]); |
|
||||||
*self = b; |
|
||||||
Ok(amt) |
|
||||||
} |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn write_all(&mut self, data: &[u8]) -> io::Result<()> { |
|
||||||
if self.write(data)? == data.len() { |
|
||||||
Ok(()) |
|
||||||
} else { |
|
||||||
Err(Error::new(ErrorKind::WriteZero, "failed to write whole buffer")) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn flush(&mut self) -> io::Result<()> { Ok(()) } |
|
||||||
} |
|
||||||
|
|
||||||
/// Write is implemented for `Vec<u8>` by appending to the vector.
|
|
||||||
/// The vector will grow as needed.
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl Write for Vec<u8> { |
|
||||||
#[inline] |
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
|
||||||
self.extend_from_slice(buf); |
|
||||||
Ok(buf.len()) |
|
||||||
} |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { |
|
||||||
self.extend_from_slice(buf); |
|
||||||
Ok(()) |
|
||||||
} |
|
||||||
|
|
||||||
#[inline] |
|
||||||
fn flush(&mut self) -> io::Result<()> { Ok(()) } |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(test)] |
|
||||||
mod tests { |
|
||||||
use io::prelude::*; |
|
||||||
use test; |
|
||||||
|
|
||||||
#[bench] |
|
||||||
fn bench_read_slice(b: &mut test::Bencher) { |
|
||||||
let buf = [5; 1024]; |
|
||||||
let mut dst = [0; 128]; |
|
||||||
|
|
||||||
b.iter(|| { |
|
||||||
let mut rd = &buf[..]; |
|
||||||
for _ in 0..8 { |
|
||||||
let _ = rd.read(&mut dst); |
|
||||||
test::black_box(&dst); |
|
||||||
} |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
#[bench] |
|
||||||
fn bench_write_slice(b: &mut test::Bencher) { |
|
||||||
let mut buf = [0; 1024]; |
|
||||||
let src = [5; 128]; |
|
||||||
|
|
||||||
b.iter(|| { |
|
||||||
let mut wr = &mut buf[..]; |
|
||||||
for _ in 0..8 { |
|
||||||
let _ = wr.write_all(&src); |
|
||||||
test::black_box(&wr); |
|
||||||
} |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
#[bench] |
|
||||||
fn bench_read_vec(b: &mut test::Bencher) { |
|
||||||
let buf = vec![5; 1024]; |
|
||||||
let mut dst = [0; 128]; |
|
||||||
|
|
||||||
b.iter(|| { |
|
||||||
let mut rd = &buf[..]; |
|
||||||
for _ in 0..8 { |
|
||||||
let _ = rd.read(&mut dst); |
|
||||||
test::black_box(&dst); |
|
||||||
} |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
#[bench] |
|
||||||
fn bench_write_vec(b: &mut test::Bencher) { |
|
||||||
let mut buf = Vec::with_capacity(1024); |
|
||||||
let src = [5; 128]; |
|
||||||
|
|
||||||
b.iter(|| { |
|
||||||
let mut wr = &mut buf[..]; |
|
||||||
for _ in 0..8 { |
|
||||||
let _ = wr.write_all(&src); |
|
||||||
test::black_box(&wr); |
|
||||||
} |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
@ -1,76 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
use cell::Cell; |
|
||||||
use ptr; |
|
||||||
use sync::Arc; |
|
||||||
use sys_common; |
|
||||||
use sys_common::mutex::Mutex; |
|
||||||
|
|
||||||
pub struct Lazy<T> { |
|
||||||
// We never call `lock.init()`, so it is UB to attempt to acquire this mutex reentrantly!
|
|
||||||
lock: Mutex, |
|
||||||
ptr: Cell<*mut Arc<T>>, |
|
||||||
init: fn() -> Arc<T>, |
|
||||||
} |
|
||||||
|
|
||||||
#[inline] |
|
||||||
const fn done<T>() -> *mut Arc<T> { 1_usize as *mut _ } |
|
||||||
|
|
||||||
unsafe impl<T> Sync for Lazy<T> {} |
|
||||||
|
|
||||||
impl<T: Send + Sync + 'static> Lazy<T> { |
|
||||||
/// Safety: `init` must not call `get` on the variable that is being
|
|
||||||
/// initialized.
|
|
||||||
pub const unsafe fn new(init: fn() -> Arc<T>) -> Lazy<T> { |
|
||||||
Lazy { |
|
||||||
lock: Mutex::new(), |
|
||||||
ptr: Cell::new(ptr::null_mut()), |
|
||||||
init, |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
pub fn get(&'static self) -> Option<Arc<T>> { |
|
||||||
unsafe { |
|
||||||
let _guard = self.lock.lock(); |
|
||||||
let ptr = self.ptr.get(); |
|
||||||
if ptr.is_null() { |
|
||||||
Some(self.init()) |
|
||||||
} else if ptr == done() { |
|
||||||
None |
|
||||||
} else { |
|
||||||
Some((*ptr).clone()) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// Must only be called with `lock` held
|
|
||||||
unsafe fn init(&'static self) -> Arc<T> { |
|
||||||
// If we successfully register an at exit handler, then we cache the
|
|
||||||
// `Arc` allocation in our own internal box (it will get deallocated by
|
|
||||||
// the at exit handler). Otherwise we just return the freshly allocated
|
|
||||||
// `Arc`.
|
|
||||||
let registered = sys_common::at_exit(move || { |
|
||||||
let ptr = { |
|
||||||
let _guard = self.lock.lock(); |
|
||||||
self.ptr.replace(done()) |
|
||||||
}; |
|
||||||
drop(Box::from_raw(ptr)) |
|
||||||
}); |
|
||||||
// This could reentrantly call `init` again, which is a problem
|
|
||||||
// because our `lock` allows reentrancy!
|
|
||||||
// That's why `new` is unsafe and requires the caller to ensure no reentrancy happens.
|
|
||||||
let ret = (self.init)(); |
|
||||||
if registered.is_ok() { |
|
||||||
self.ptr.set(Box::into_raw(Box::new(ret.clone()))); |
|
||||||
} |
|
||||||
ret |
|
||||||
} |
|
||||||
} |
|
@ -1,24 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! The I/O Prelude
|
|
||||||
//!
|
|
||||||
//! The purpose of this module is to alleviate imports of many common I/O traits
|
|
||||||
//! by adding a glob import to the top of I/O heavy modules:
|
|
||||||
//!
|
|
||||||
//! ```
|
|
||||||
//! # #![allow(unused_imports)]
|
|
||||||
//! use std::io::prelude::*;
|
|
||||||
//! ```
|
|
||||||
|
|
||||||
#![stable(feature = "rust1", since = "1.0.0")] |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use super::{Read, Write, BufRead, Seek}; |
|
@ -1,764 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
use io::prelude::*; |
|
||||||
|
|
||||||
use cell::RefCell; |
|
||||||
use fmt; |
|
||||||
use io::lazy::Lazy; |
|
||||||
use io::{self, Initializer, BufReader, LineWriter}; |
|
||||||
use sync::{Arc, Mutex, MutexGuard}; |
|
||||||
use sys::stdio; |
|
||||||
use sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard}; |
|
||||||
use thread::LocalKey; |
|
||||||
|
|
||||||
/// Stdout used by print! and println! macros
|
|
||||||
thread_local! { |
|
||||||
static LOCAL_STDOUT: RefCell<Option<Box<dyn Write + Send>>> = { |
|
||||||
RefCell::new(None) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// A handle to a raw instance of the standard input stream of this process.
|
|
||||||
///
|
|
||||||
/// This handle is not synchronized or buffered in any fashion. Constructed via
|
|
||||||
/// the `std::io::stdio::stdin_raw` function.
|
|
||||||
struct StdinRaw(stdio::Stdin); |
|
||||||
|
|
||||||
/// A handle to a raw instance of the standard output stream of this process.
|
|
||||||
///
|
|
||||||
/// This handle is not synchronized or buffered in any fashion. Constructed via
|
|
||||||
/// the `std::io::stdio::stdout_raw` function.
|
|
||||||
struct StdoutRaw(stdio::Stdout); |
|
||||||
|
|
||||||
/// A handle to a raw instance of the standard output stream of this process.
|
|
||||||
///
|
|
||||||
/// This handle is not synchronized or buffered in any fashion. Constructed via
|
|
||||||
/// the `std::io::stdio::stderr_raw` function.
|
|
||||||
struct StderrRaw(stdio::Stderr); |
|
||||||
|
|
||||||
/// Constructs a new raw handle to the standard input of this process.
|
|
||||||
///
|
|
||||||
/// The returned handle does not interact with any other handles created nor
|
|
||||||
/// handles returned by `std::io::stdin`. Data buffered by the `std::io::stdin`
|
|
||||||
/// handles is **not** available to raw handles returned from this function.
|
|
||||||
///
|
|
||||||
/// The returned handle has no external synchronization or buffering.
|
|
||||||
fn stdin_raw() -> io::Result<StdinRaw> { stdio::Stdin::new().map(StdinRaw) } |
|
||||||
|
|
||||||
/// Constructs a new raw handle to the standard output stream of this process.
|
|
||||||
///
|
|
||||||
/// The returned handle does not interact with any other handles created nor
|
|
||||||
/// handles returned by `std::io::stdout`. Note that data is buffered by the
|
|
||||||
/// `std::io::stdout` handles so writes which happen via this raw handle may
|
|
||||||
/// appear before previous writes.
|
|
||||||
///
|
|
||||||
/// The returned handle has no external synchronization or buffering layered on
|
|
||||||
/// top.
|
|
||||||
fn stdout_raw() -> io::Result<StdoutRaw> { stdio::Stdout::new().map(StdoutRaw) } |
|
||||||
|
|
||||||
/// Constructs a new raw handle to the standard error stream of this process.
|
|
||||||
///
|
|
||||||
/// The returned handle does not interact with any other handles created nor
|
|
||||||
/// handles returned by `std::io::stderr`.
|
|
||||||
///
|
|
||||||
/// The returned handle has no external synchronization or buffering layered on
|
|
||||||
/// top.
|
|
||||||
fn stderr_raw() -> io::Result<StderrRaw> { stdio::Stderr::new().map(StderrRaw) } |
|
||||||
|
|
||||||
impl Read for StdinRaw { |
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) } |
|
||||||
|
|
||||||
#[inline] |
|
||||||
unsafe fn initializer(&self) -> Initializer { |
|
||||||
Initializer::nop() |
|
||||||
} |
|
||||||
} |
|
||||||
impl Write for StdoutRaw { |
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) } |
|
||||||
fn flush(&mut self) -> io::Result<()> { self.0.flush() } |
|
||||||
} |
|
||||||
impl Write for StderrRaw { |
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) } |
|
||||||
fn flush(&mut self) -> io::Result<()> { self.0.flush() } |
|
||||||
} |
|
||||||
|
|
||||||
enum Maybe<T> { |
|
||||||
Real(T), |
|
||||||
Fake, |
|
||||||
} |
|
||||||
|
|
||||||
impl<W: io::Write> io::Write for Maybe<W> { |
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
|
||||||
match *self { |
|
||||||
Maybe::Real(ref mut w) => handle_ebadf(w.write(buf), buf.len()), |
|
||||||
Maybe::Fake => Ok(buf.len()) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fn flush(&mut self) -> io::Result<()> { |
|
||||||
match *self { |
|
||||||
Maybe::Real(ref mut w) => handle_ebadf(w.flush(), ()), |
|
||||||
Maybe::Fake => Ok(()) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl<R: io::Read> io::Read for Maybe<R> { |
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
|
||||||
match *self { |
|
||||||
Maybe::Real(ref mut r) => handle_ebadf(r.read(buf), 0), |
|
||||||
Maybe::Fake => Ok(0) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> { |
|
||||||
match r { |
|
||||||
Err(ref e) if stdio::is_ebadf(e) => Ok(default), |
|
||||||
r => r |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// A handle to the standard input stream of a process.
|
|
||||||
///
|
|
||||||
/// Each handle is a shared reference to a global buffer of input data to this
|
|
||||||
/// process. A handle can be `lock`'d to gain full access to [`BufRead`] methods
|
|
||||||
/// (e.g. `.lines()`). Reads to this handle are otherwise locked with respect
|
|
||||||
/// to other reads.
|
|
||||||
///
|
|
||||||
/// This handle implements the `Read` trait, but beware that concurrent reads
|
|
||||||
/// of `Stdin` must be executed with care.
|
|
||||||
///
|
|
||||||
/// Created by the [`io::stdin`] method.
|
|
||||||
///
|
|
||||||
/// [`io::stdin`]: fn.stdin.html
|
|
||||||
/// [`BufRead`]: trait.BufRead.html
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub struct Stdin { |
|
||||||
inner: Arc<Mutex<BufReader<Maybe<StdinRaw>>>>, |
|
||||||
} |
|
||||||
|
|
||||||
/// A locked reference to the `Stdin` handle.
|
|
||||||
///
|
|
||||||
/// This handle implements both the [`Read`] and [`BufRead`] traits, and
|
|
||||||
/// is constructed via the [`Stdin::lock`] method.
|
|
||||||
///
|
|
||||||
/// [`Read`]: trait.Read.html
|
|
||||||
/// [`BufRead`]: trait.BufRead.html
|
|
||||||
/// [`Stdin::lock`]: struct.Stdin.html#method.lock
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub struct StdinLock<'a> { |
|
||||||
inner: MutexGuard<'a, BufReader<Maybe<StdinRaw>>>, |
|
||||||
} |
|
||||||
|
|
||||||
/// Constructs a new handle to the standard input of the current process.
|
|
||||||
///
|
|
||||||
/// Each handle returned is a reference to a shared global buffer whose access
|
|
||||||
/// is synchronized via a mutex. If you need more explicit control over
|
|
||||||
/// locking, see the [`lock() method`][lock].
|
|
||||||
///
|
|
||||||
/// [lock]: struct.Stdin.html#method.lock
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// Using implicit synchronization:
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::io::{self, Read};
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let mut buffer = String::new();
|
|
||||||
/// io::stdin().read_to_string(&mut buffer)?;
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Using explicit synchronization:
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::io::{self, Read};
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let mut buffer = String::new();
|
|
||||||
/// let stdin = io::stdin();
|
|
||||||
/// let mut handle = stdin.lock();
|
|
||||||
///
|
|
||||||
/// handle.read_to_string(&mut buffer)?;
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub fn stdin() -> Stdin { |
|
||||||
static INSTANCE: Lazy<Mutex<BufReader<Maybe<StdinRaw>>>> = unsafe { Lazy::new(stdin_init) }; |
|
||||||
return Stdin { |
|
||||||
inner: INSTANCE.get().expect("cannot access stdin during shutdown"), |
|
||||||
}; |
|
||||||
|
|
||||||
fn stdin_init() -> Arc<Mutex<BufReader<Maybe<StdinRaw>>>> { |
|
||||||
// This must not reentrantly access `INSTANCE`
|
|
||||||
let stdin = match stdin_raw() { |
|
||||||
Ok(stdin) => Maybe::Real(stdin), |
|
||||||
_ => Maybe::Fake |
|
||||||
}; |
|
||||||
|
|
||||||
Arc::new(Mutex::new(BufReader::with_capacity(stdio::STDIN_BUF_SIZE, stdin))) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl Stdin { |
|
||||||
/// Locks this handle to the standard input stream, returning a readable
|
|
||||||
/// guard.
|
|
||||||
///
|
|
||||||
/// The lock is released when the returned lock goes out of scope. The
|
|
||||||
/// returned guard also implements the [`Read`] and [`BufRead`] traits for
|
|
||||||
/// accessing the underlying data.
|
|
||||||
///
|
|
||||||
/// [`Read`]: trait.Read.html
|
|
||||||
/// [`BufRead`]: trait.BufRead.html
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::io::{self, Read};
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let mut buffer = String::new();
|
|
||||||
/// let stdin = io::stdin();
|
|
||||||
/// let mut handle = stdin.lock();
|
|
||||||
///
|
|
||||||
/// handle.read_to_string(&mut buffer)?;
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub fn lock(&self) -> StdinLock { |
|
||||||
StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) } |
|
||||||
} |
|
||||||
|
|
||||||
/// Locks this handle and reads a line of input into the specified buffer.
|
|
||||||
///
|
|
||||||
/// For detailed semantics of this method, see the documentation on
|
|
||||||
/// [`BufRead::read_line`].
|
|
||||||
///
|
|
||||||
/// [`BufRead::read_line`]: trait.BufRead.html#method.read_line
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::io;
|
|
||||||
///
|
|
||||||
/// let mut input = String::new();
|
|
||||||
/// match io::stdin().read_line(&mut input) {
|
|
||||||
/// Ok(n) => {
|
|
||||||
/// println!("{} bytes read", n);
|
|
||||||
/// println!("{}", input);
|
|
||||||
/// }
|
|
||||||
/// Err(error) => println!("error: {}", error),
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// You can run the example one of two ways:
|
|
||||||
///
|
|
||||||
/// - Pipe some text to it, e.g. `printf foo | path/to/executable`
|
|
||||||
/// - Give it text interactively by running the executable directly,
|
|
||||||
/// in which case it will wait for the Enter key to be pressed before
|
|
||||||
/// continuing
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub fn read_line(&self, buf: &mut String) -> io::Result<usize> { |
|
||||||
self.lock().read_line(buf) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "std_debug", since = "1.16.0")] |
|
||||||
impl fmt::Debug for Stdin { |
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
|
||||||
f.pad("Stdin { .. }") |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl Read for Stdin { |
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
|
||||||
self.lock().read(buf) |
|
||||||
} |
|
||||||
#[inline] |
|
||||||
unsafe fn initializer(&self) -> Initializer { |
|
||||||
Initializer::nop() |
|
||||||
} |
|
||||||
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> { |
|
||||||
self.lock().read_to_end(buf) |
|
||||||
} |
|
||||||
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> { |
|
||||||
self.lock().read_to_string(buf) |
|
||||||
} |
|
||||||
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { |
|
||||||
self.lock().read_exact(buf) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl<'a> Read for StdinLock<'a> { |
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
|
||||||
self.inner.read(buf) |
|
||||||
} |
|
||||||
#[inline] |
|
||||||
unsafe fn initializer(&self) -> Initializer { |
|
||||||
Initializer::nop() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl<'a> BufRead for StdinLock<'a> { |
|
||||||
fn fill_buf(&mut self) -> io::Result<&[u8]> { self.inner.fill_buf() } |
|
||||||
fn consume(&mut self, n: usize) { self.inner.consume(n) } |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "std_debug", since = "1.16.0")] |
|
||||||
impl<'a> fmt::Debug for StdinLock<'a> { |
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
|
||||||
f.pad("StdinLock { .. }") |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// A handle to the global standard output stream of the current process.
|
|
||||||
///
|
|
||||||
/// Each handle shares a global buffer of data to be written to the standard
|
|
||||||
/// output stream. Access is also synchronized via a lock and explicit control
|
|
||||||
/// over locking is available via the [`lock`] method.
|
|
||||||
///
|
|
||||||
/// Created by the [`io::stdout`] method.
|
|
||||||
///
|
|
||||||
/// [`lock`]: #method.lock
|
|
||||||
/// [`io::stdout`]: fn.stdout.html
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub struct Stdout { |
|
||||||
// FIXME: this should be LineWriter or BufWriter depending on the state of
|
|
||||||
// stdout (tty or not). Note that if this is not line buffered it
|
|
||||||
// should also flush-on-panic or some form of flush-on-abort.
|
|
||||||
inner: Arc<ReentrantMutex<RefCell<LineWriter<Maybe<StdoutRaw>>>>>, |
|
||||||
} |
|
||||||
|
|
||||||
/// A locked reference to the `Stdout` handle.
|
|
||||||
///
|
|
||||||
/// This handle implements the [`Write`] trait, and is constructed via
|
|
||||||
/// the [`Stdout::lock`] method.
|
|
||||||
///
|
|
||||||
/// [`Write`]: trait.Write.html
|
|
||||||
/// [`Stdout::lock`]: struct.Stdout.html#method.lock
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub struct StdoutLock<'a> { |
|
||||||
inner: ReentrantMutexGuard<'a, RefCell<LineWriter<Maybe<StdoutRaw>>>>, |
|
||||||
} |
|
||||||
|
|
||||||
/// Constructs a new handle to the standard output of the current process.
|
|
||||||
///
|
|
||||||
/// Each handle returned is a reference to a shared global buffer whose access
|
|
||||||
/// is synchronized via a mutex. If you need more explicit control over
|
|
||||||
/// locking, see the [Stdout::lock] method.
|
|
||||||
///
|
|
||||||
/// [Stdout::lock]: struct.Stdout.html#method.lock
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// Using implicit synchronization:
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::io::{self, Write};
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// io::stdout().write(b"hello world")?;
|
|
||||||
///
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Using explicit synchronization:
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::io::{self, Write};
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let stdout = io::stdout();
|
|
||||||
/// let mut handle = stdout.lock();
|
|
||||||
///
|
|
||||||
/// handle.write(b"hello world")?;
|
|
||||||
///
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub fn stdout() -> Stdout { |
|
||||||
static INSTANCE: Lazy<ReentrantMutex<RefCell<LineWriter<Maybe<StdoutRaw>>>>> |
|
||||||
= unsafe { Lazy::new(stdout_init) }; |
|
||||||
return Stdout { |
|
||||||
inner: INSTANCE.get().expect("cannot access stdout during shutdown"), |
|
||||||
}; |
|
||||||
|
|
||||||
fn stdout_init() -> Arc<ReentrantMutex<RefCell<LineWriter<Maybe<StdoutRaw>>>>> { |
|
||||||
// This must not reentrantly access `INSTANCE`
|
|
||||||
let stdout = match stdout_raw() { |
|
||||||
Ok(stdout) => Maybe::Real(stdout), |
|
||||||
_ => Maybe::Fake, |
|
||||||
}; |
|
||||||
Arc::new(ReentrantMutex::new(RefCell::new(LineWriter::new(stdout)))) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl Stdout { |
|
||||||
/// Locks this handle to the standard output stream, returning a writable
|
|
||||||
/// guard.
|
|
||||||
///
|
|
||||||
/// The lock is released when the returned lock goes out of scope. The
|
|
||||||
/// returned guard also implements the `Write` trait for writing data.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::io::{self, Write};
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let stdout = io::stdout();
|
|
||||||
/// let mut handle = stdout.lock();
|
|
||||||
///
|
|
||||||
/// handle.write(b"hello world")?;
|
|
||||||
///
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub fn lock(&self) -> StdoutLock { |
|
||||||
StdoutLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) } |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "std_debug", since = "1.16.0")] |
|
||||||
impl fmt::Debug for Stdout { |
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
|
||||||
f.pad("Stdout { .. }") |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl Write for Stdout { |
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
|
||||||
self.lock().write(buf) |
|
||||||
} |
|
||||||
fn flush(&mut self) -> io::Result<()> { |
|
||||||
self.lock().flush() |
|
||||||
} |
|
||||||
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { |
|
||||||
self.lock().write_all(buf) |
|
||||||
} |
|
||||||
fn write_fmt(&mut self, args: fmt::Arguments) -> io::Result<()> { |
|
||||||
self.lock().write_fmt(args) |
|
||||||
} |
|
||||||
} |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl<'a> Write for StdoutLock<'a> { |
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
|
||||||
self.inner.borrow_mut().write(buf) |
|
||||||
} |
|
||||||
fn flush(&mut self) -> io::Result<()> { |
|
||||||
self.inner.borrow_mut().flush() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "std_debug", since = "1.16.0")] |
|
||||||
impl<'a> fmt::Debug for StdoutLock<'a> { |
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
|
||||||
f.pad("StdoutLock { .. }") |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// A handle to the standard error stream of a process.
|
|
||||||
///
|
|
||||||
/// For more information, see the [`io::stderr`] method.
|
|
||||||
///
|
|
||||||
/// [`io::stderr`]: fn.stderr.html
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub struct Stderr { |
|
||||||
inner: Arc<ReentrantMutex<RefCell<Maybe<StderrRaw>>>>, |
|
||||||
} |
|
||||||
|
|
||||||
/// A locked reference to the `Stderr` handle.
|
|
||||||
///
|
|
||||||
/// This handle implements the `Write` trait and is constructed via
|
|
||||||
/// the [`Stderr::lock`] method.
|
|
||||||
///
|
|
||||||
/// [`Stderr::lock`]: struct.Stderr.html#method.lock
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub struct StderrLock<'a> { |
|
||||||
inner: ReentrantMutexGuard<'a, RefCell<Maybe<StderrRaw>>>, |
|
||||||
} |
|
||||||
|
|
||||||
/// Constructs a new handle to the standard error of the current process.
|
|
||||||
///
|
|
||||||
/// This handle is not buffered.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// Using implicit synchronization:
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::io::{self, Write};
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// io::stderr().write(b"hello world")?;
|
|
||||||
///
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Using explicit synchronization:
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::io::{self, Write};
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let stderr = io::stderr();
|
|
||||||
/// let mut handle = stderr.lock();
|
|
||||||
///
|
|
||||||
/// handle.write(b"hello world")?;
|
|
||||||
///
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub fn stderr() -> Stderr { |
|
||||||
static INSTANCE: Lazy<ReentrantMutex<RefCell<Maybe<StderrRaw>>>> = |
|
||||||
unsafe { Lazy::new(stderr_init) }; |
|
||||||
return Stderr { |
|
||||||
inner: INSTANCE.get().expect("cannot access stderr during shutdown"), |
|
||||||
}; |
|
||||||
|
|
||||||
fn stderr_init() -> Arc<ReentrantMutex<RefCell<Maybe<StderrRaw>>>> { |
|
||||||
// This must not reentrantly access `INSTANCE`
|
|
||||||
let stderr = match stderr_raw() { |
|
||||||
Ok(stderr) => Maybe::Real(stderr), |
|
||||||
_ => Maybe::Fake, |
|
||||||
}; |
|
||||||
Arc::new(ReentrantMutex::new(RefCell::new(stderr))) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl Stderr { |
|
||||||
/// Locks this handle to the standard error stream, returning a writable
|
|
||||||
/// guard.
|
|
||||||
///
|
|
||||||
/// The lock is released when the returned lock goes out of scope. The
|
|
||||||
/// returned guard also implements the `Write` trait for writing data.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::io::{self, Write};
|
|
||||||
///
|
|
||||||
/// fn foo() -> io::Result<()> {
|
|
||||||
/// let stderr = io::stderr();
|
|
||||||
/// let mut handle = stderr.lock();
|
|
||||||
///
|
|
||||||
/// handle.write(b"hello world")?;
|
|
||||||
///
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub fn lock(&self) -> StderrLock { |
|
||||||
StderrLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) } |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "std_debug", since = "1.16.0")] |
|
||||||
impl fmt::Debug for Stderr { |
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
|
||||||
f.pad("Stderr { .. }") |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl Write for Stderr { |
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
|
||||||
self.lock().write(buf) |
|
||||||
} |
|
||||||
fn flush(&mut self) -> io::Result<()> { |
|
||||||
self.lock().flush() |
|
||||||
} |
|
||||||
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { |
|
||||||
self.lock().write_all(buf) |
|
||||||
} |
|
||||||
fn write_fmt(&mut self, args: fmt::Arguments) -> io::Result<()> { |
|
||||||
self.lock().write_fmt(args) |
|
||||||
} |
|
||||||
} |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl<'a> Write for StderrLock<'a> { |
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
|
||||||
self.inner.borrow_mut().write(buf) |
|
||||||
} |
|
||||||
fn flush(&mut self) -> io::Result<()> { |
|
||||||
self.inner.borrow_mut().flush() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "std_debug", since = "1.16.0")] |
|
||||||
impl<'a> fmt::Debug for StderrLock<'a> { |
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
|
||||||
f.pad("StderrLock { .. }") |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// Resets the thread-local stderr handle to the specified writer
|
|
||||||
///
|
|
||||||
/// This will replace the current thread's stderr handle, returning the old
|
|
||||||
/// handle. All future calls to `panic!` and friends will emit their output to
|
|
||||||
/// this specified handle.
|
|
||||||
///
|
|
||||||
/// Note that this does not need to be called for all new threads; the default
|
|
||||||
/// output handle is to the process's stderr stream.
|
|
||||||
#[unstable(feature = "set_stdio",
|
|
||||||
reason = "this function may disappear completely or be replaced \ |
|
||||||
with a more general mechanism", |
|
||||||
issue = "0")] |
|
||||||
#[doc(hidden)] |
|
||||||
pub fn set_panic(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write + Send>> { |
|
||||||
use panicking::LOCAL_STDERR; |
|
||||||
use mem; |
|
||||||
LOCAL_STDERR.with(move |slot| { |
|
||||||
mem::replace(&mut *slot.borrow_mut(), sink) |
|
||||||
}).and_then(|mut s| { |
|
||||||
let _ = s.flush(); |
|
||||||
Some(s) |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
/// Resets the thread-local stdout handle to the specified writer
|
|
||||||
///
|
|
||||||
/// This will replace the current thread's stdout handle, returning the old
|
|
||||||
/// handle. All future calls to `print!` and friends will emit their output to
|
|
||||||
/// this specified handle.
|
|
||||||
///
|
|
||||||
/// Note that this does not need to be called for all new threads; the default
|
|
||||||
/// output handle is to the process's stdout stream.
|
|
||||||
#[unstable(feature = "set_stdio",
|
|
||||||
reason = "this function may disappear completely or be replaced \ |
|
||||||
with a more general mechanism", |
|
||||||
issue = "0")] |
|
||||||
#[doc(hidden)] |
|
||||||
pub fn set_print(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write + Send>> { |
|
||||||
use mem; |
|
||||||
LOCAL_STDOUT.with(move |slot| { |
|
||||||
mem::replace(&mut *slot.borrow_mut(), sink) |
|
||||||
}).and_then(|mut s| { |
|
||||||
let _ = s.flush(); |
|
||||||
Some(s) |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
/// Write `args` to output stream `local_s` if possible, `global_s`
|
|
||||||
/// otherwise. `label` identifies the stream in a panic message.
|
|
||||||
///
|
|
||||||
/// This function is used to print error messages, so it takes extra
|
|
||||||
/// care to avoid causing a panic when `local_stream` is unusable.
|
|
||||||
/// For instance, if the TLS key for the local stream is
|
|
||||||
/// already destroyed, or if the local stream is locked by another
|
|
||||||
/// thread, it will just fall back to the global stream.
|
|
||||||
///
|
|
||||||
/// However, if the actual I/O causes an error, this function does panic.
|
|
||||||
fn print_to<T>( |
|
||||||
args: fmt::Arguments, |
|
||||||
local_s: &'static LocalKey<RefCell<Option<Box<dyn Write+Send>>>>, |
|
||||||
global_s: fn() -> T, |
|
||||||
label: &str, |
|
||||||
) |
|
||||||
where |
|
||||||
T: Write, |
|
||||||
{ |
|
||||||
let result = local_s.try_with(|s| { |
|
||||||
if let Ok(mut borrowed) = s.try_borrow_mut() { |
|
||||||
if let Some(w) = borrowed.as_mut() { |
|
||||||
return w.write_fmt(args); |
|
||||||
} |
|
||||||
} |
|
||||||
global_s().write_fmt(args) |
|
||||||
}).unwrap_or_else(|_| { |
|
||||||
global_s().write_fmt(args) |
|
||||||
}); |
|
||||||
|
|
||||||
if let Err(e) = result { |
|
||||||
panic!("failed printing to {}: {}", label, e); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[unstable(feature = "print_internals",
|
|
||||||
reason = "implementation detail which may disappear or be replaced at any time", |
|
||||||
issue = "0")] |
|
||||||
#[doc(hidden)] |
|
||||||
pub fn _print(args: fmt::Arguments) { |
|
||||||
print_to(args, &LOCAL_STDOUT, stdout, "stdout"); |
|
||||||
} |
|
||||||
|
|
||||||
#[unstable(feature = "print_internals",
|
|
||||||
reason = "implementation detail which may disappear or be replaced at any time", |
|
||||||
issue = "0")] |
|
||||||
#[doc(hidden)] |
|
||||||
pub fn _eprint(args: fmt::Arguments) { |
|
||||||
use panicking::LOCAL_STDERR; |
|
||||||
print_to(args, &LOCAL_STDERR, stderr, "stderr"); |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(test)] |
|
||||||
mod tests { |
|
||||||
use panic::{UnwindSafe, RefUnwindSafe}; |
|
||||||
use thread; |
|
||||||
use super::*; |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn stdout_unwind_safe() { |
|
||||||
assert_unwind_safe::<Stdout>(); |
|
||||||
} |
|
||||||
#[test] |
|
||||||
fn stdoutlock_unwind_safe() { |
|
||||||
assert_unwind_safe::<StdoutLock>(); |
|
||||||
assert_unwind_safe::<StdoutLock<'static>>(); |
|
||||||
} |
|
||||||
#[test] |
|
||||||
fn stderr_unwind_safe() { |
|
||||||
assert_unwind_safe::<Stderr>(); |
|
||||||
} |
|
||||||
#[test] |
|
||||||
fn stderrlock_unwind_safe() { |
|
||||||
assert_unwind_safe::<StderrLock>(); |
|
||||||
assert_unwind_safe::<StderrLock<'static>>(); |
|
||||||
} |
|
||||||
|
|
||||||
fn assert_unwind_safe<T: UnwindSafe + RefUnwindSafe>() {} |
|
||||||
|
|
||||||
#[test] |
|
||||||
#[cfg_attr(target_os = "emscripten", ignore)] |
|
||||||
fn panic_doesnt_poison() { |
|
||||||
thread::spawn(|| { |
|
||||||
let _a = stdin(); |
|
||||||
let _a = _a.lock(); |
|
||||||
let _a = stdout(); |
|
||||||
let _a = _a.lock(); |
|
||||||
let _a = stderr(); |
|
||||||
let _a = _a.lock(); |
|
||||||
panic!(); |
|
||||||
}).join().unwrap_err(); |
|
||||||
|
|
||||||
let _a = stdin(); |
|
||||||
let _a = _a.lock(); |
|
||||||
let _a = stdout(); |
|
||||||
let _a = _a.lock(); |
|
||||||
let _a = stderr(); |
|
||||||
let _a = _a.lock(); |
|
||||||
} |
|
||||||
} |
|
@ -1,261 +0,0 @@ |
|||||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#![allow(missing_copy_implementations)] |
|
||||||
|
|
||||||
use fmt; |
|
||||||
use io::{self, Read, Initializer, Write, ErrorKind, BufRead}; |
|
||||||
use mem; |
|
||||||
|
|
||||||
/// Copies the entire contents of a reader into a writer.
|
|
||||||
///
|
|
||||||
/// This function will continuously read data from `reader` and then
|
|
||||||
/// write it into `writer` in a streaming fashion until `reader`
|
|
||||||
/// returns EOF.
|
|
||||||
///
|
|
||||||
/// On success, the total number of bytes that were copied from
|
|
||||||
/// `reader` to `writer` is returned.
|
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// This function will return an error immediately if any call to `read` or
|
|
||||||
/// `write` returns an error. All instances of `ErrorKind::Interrupted` are
|
|
||||||
/// handled by this function and the underlying operation is retried.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::io;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let mut reader: &[u8] = b"hello";
|
|
||||||
/// let mut writer: Vec<u8> = vec![];
|
|
||||||
///
|
|
||||||
/// io::copy(&mut reader, &mut writer)?;
|
|
||||||
///
|
|
||||||
/// assert_eq!(&b"hello"[..], &writer[..]);
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> io::Result<u64> |
|
||||||
where R: Read, W: Write |
|
||||||
{ |
|
||||||
let mut buf = unsafe { |
|
||||||
let mut buf: [u8; super::DEFAULT_BUF_SIZE] = mem::uninitialized(); |
|
||||||
reader.initializer().initialize(&mut buf); |
|
||||||
buf |
|
||||||
}; |
|
||||||
|
|
||||||
let mut written = 0; |
|
||||||
loop { |
|
||||||
let len = match reader.read(&mut buf) { |
|
||||||
Ok(0) => return Ok(written), |
|
||||||
Ok(len) => len, |
|
||||||
Err(ref e) if e.kind() == ErrorKind::Interrupted => continue, |
|
||||||
Err(e) => return Err(e), |
|
||||||
}; |
|
||||||
writer.write_all(&buf[..len])?; |
|
||||||
written += len as u64; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// A reader which is always at EOF.
|
|
||||||
///
|
|
||||||
/// This struct is generally created by calling [`empty`]. Please see
|
|
||||||
/// the documentation of [`empty()`][`empty`] for more details.
|
|
||||||
///
|
|
||||||
/// [`empty`]: fn.empty.html
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub struct Empty { _priv: () } |
|
||||||
|
|
||||||
/// Constructs a new handle to an empty reader.
|
|
||||||
///
|
|
||||||
/// All reads from the returned reader will return [`Ok`]`(0)`.
|
|
||||||
///
|
|
||||||
/// [`Ok`]: ../result/enum.Result.html#variant.Ok
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// A slightly sad example of not reading anything into a buffer:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::io::{self, Read};
|
|
||||||
///
|
|
||||||
/// let mut buffer = String::new();
|
|
||||||
/// io::empty().read_to_string(&mut buffer).unwrap();
|
|
||||||
/// assert!(buffer.is_empty());
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub fn empty() -> Empty { Empty { _priv: () } } |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl Read for Empty { |
|
||||||
#[inline] |
|
||||||
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { Ok(0) } |
|
||||||
|
|
||||||
#[inline] |
|
||||||
unsafe fn initializer(&self) -> Initializer { |
|
||||||
Initializer::nop() |
|
||||||
} |
|
||||||
} |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl BufRead for Empty { |
|
||||||
#[inline] |
|
||||||
fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(&[]) } |
|
||||||
#[inline] |
|
||||||
fn consume(&mut self, _n: usize) {} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "std_debug", since = "1.16.0")] |
|
||||||
impl fmt::Debug for Empty { |
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
|
||||||
f.pad("Empty { .. }") |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// A reader which yields one byte over and over and over and over and over and...
|
|
||||||
///
|
|
||||||
/// This struct is generally created by calling [`repeat`][repeat]. Please
|
|
||||||
/// see the documentation of `repeat()` for more details.
|
|
||||||
///
|
|
||||||
/// [repeat]: fn.repeat.html
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub struct Repeat { byte: u8 } |
|
||||||
|
|
||||||
/// Creates an instance of a reader that infinitely repeats one byte.
|
|
||||||
///
|
|
||||||
/// All reads from this reader will succeed by filling the specified buffer with
|
|
||||||
/// the given byte.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::io::{self, Read};
|
|
||||||
///
|
|
||||||
/// let mut buffer = [0; 3];
|
|
||||||
/// io::repeat(0b101).read_exact(&mut buffer).unwrap();
|
|
||||||
/// assert_eq!(buffer, [0b101, 0b101, 0b101]);
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub fn repeat(byte: u8) -> Repeat { Repeat { byte: byte } } |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl Read for Repeat { |
|
||||||
#[inline] |
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
|
||||||
for slot in &mut *buf { |
|
||||||
*slot = self.byte; |
|
||||||
} |
|
||||||
Ok(buf.len()) |
|
||||||
} |
|
||||||
|
|
||||||
#[inline] |
|
||||||
unsafe fn initializer(&self) -> Initializer { |
|
||||||
Initializer::nop() |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "std_debug", since = "1.16.0")] |
|
||||||
impl fmt::Debug for Repeat { |
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
|
||||||
f.pad("Repeat { .. }") |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// A writer which will move data into the void.
|
|
||||||
///
|
|
||||||
/// This struct is generally created by calling [`sink`][sink]. Please
|
|
||||||
/// see the documentation of `sink()` for more details.
|
|
||||||
///
|
|
||||||
/// [sink]: fn.sink.html
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub struct Sink { _priv: () } |
|
||||||
|
|
||||||
/// Creates an instance of a writer which will successfully consume all data.
|
|
||||||
///
|
|
||||||
/// All calls to `write` on the returned instance will return `Ok(buf.len())`
|
|
||||||
/// and the contents of the buffer will not be inspected.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// use std::io::{self, Write};
|
|
||||||
///
|
|
||||||
/// let buffer = vec![1, 2, 3, 5, 8];
|
|
||||||
/// let num_bytes = io::sink().write(&buffer).unwrap();
|
|
||||||
/// assert_eq!(num_bytes, 5);
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub fn sink() -> Sink { Sink { _priv: () } } |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl Write for Sink { |
|
||||||
#[inline] |
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) } |
|
||||||
#[inline] |
|
||||||
fn flush(&mut self) -> io::Result<()> { Ok(()) } |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "std_debug", since = "1.16.0")] |
|
||||||
impl fmt::Debug for Sink { |
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
|
||||||
f.pad("Sink { .. }") |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(test)] |
|
||||||
mod tests { |
|
||||||
use io::prelude::*; |
|
||||||
use io::{copy, sink, empty, repeat}; |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn copy_copies() { |
|
||||||
let mut r = repeat(0).take(4); |
|
||||||
let mut w = sink(); |
|
||||||
assert_eq!(copy(&mut r, &mut w).unwrap(), 4); |
|
||||||
|
|
||||||
let mut r = repeat(0).take(1 << 17); |
|
||||||
assert_eq!(copy(&mut r as &mut dyn Read, &mut w as &mut dyn Write).unwrap(), 1 << 17); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn sink_sinks() { |
|
||||||
let mut s = sink(); |
|
||||||
assert_eq!(s.write(&[]).unwrap(), 0); |
|
||||||
assert_eq!(s.write(&[0]).unwrap(), 1); |
|
||||||
assert_eq!(s.write(&[0; 1024]).unwrap(), 1024); |
|
||||||
assert_eq!(s.by_ref().write(&[0; 1024]).unwrap(), 1024); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn empty_reads() { |
|
||||||
let mut e = empty(); |
|
||||||
assert_eq!(e.read(&mut []).unwrap(), 0); |
|
||||||
assert_eq!(e.read(&mut [0]).unwrap(), 0); |
|
||||||
assert_eq!(e.read(&mut [0; 1024]).unwrap(), 0); |
|
||||||
assert_eq!(e.by_ref().read(&mut [0; 1024]).unwrap(), 0); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn repeat_repeats() { |
|
||||||
let mut r = repeat(4); |
|
||||||
let mut b = [0; 1024]; |
|
||||||
assert_eq!(r.read(&mut b).unwrap(), 1024); |
|
||||||
assert!(b.iter().all(|b| *b == 4)); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn take_some_bytes() { |
|
||||||
assert_eq!(repeat(4).take(100).bytes().count(), 100); |
|
||||||
assert_eq!(repeat(4).take(100).bytes().next().unwrap().unwrap(), 4); |
|
||||||
assert_eq!(repeat(1).take(10).chain(repeat(2).take(10)).bytes().count(), 20); |
|
||||||
} |
|
||||||
} |
|
@ -1,58 +0,0 @@ |
|||||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#[doc(keyword = "fn")] |
|
||||||
//
|
|
||||||
/// The `fn` keyword.
|
|
||||||
///
|
|
||||||
/// The `fn` keyword is used to declare a function.
|
|
||||||
///
|
|
||||||
/// Example:
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// fn some_function() {
|
|
||||||
/// // code goes in here
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// For more information about functions, take a look at the [Rust Book][book].
|
|
||||||
///
|
|
||||||
/// [book]: https://doc.rust-lang.org/book/second-edition/ch03-03-how-functions-work.html
|
|
||||||
mod fn_keyword { } |
|
||||||
|
|
||||||
#[doc(keyword = "let")] |
|
||||||
//
|
|
||||||
/// The `let` keyword.
|
|
||||||
///
|
|
||||||
/// The `let` keyword is used to declare a variable.
|
|
||||||
///
|
|
||||||
/// Example:
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// # #![allow(unused_assignments)]
|
|
||||||
/// let x = 3; // We create a variable named `x` with the value `3`.
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// By default, all variables are **not** mutable. If you want a mutable variable,
|
|
||||||
/// you'll have to use the `mut` keyword.
|
|
||||||
///
|
|
||||||
/// Example:
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// # #![allow(unused_assignments)]
|
|
||||||
/// let mut x = 3; // We create a mutable variable named `x` with the value `3`.
|
|
||||||
///
|
|
||||||
/// x += 4; // `x` is now equal to `7`.
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// For more information about the `let` keyword, take a look at the [Rust Book][book].
|
|
||||||
///
|
|
||||||
/// [book]: https://doc.rust-lang.org/book/second-edition/ch03-01-variables-and-mutability.html
|
|
||||||
mod let_keyword { } |
|
@ -1,514 +0,0 @@ |
|||||||
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! # The Rust Standard Library
|
|
||||||
//!
|
|
||||||
//! The Rust Standard Library is the foundation of portable Rust software, a
|
|
||||||
//! set of minimal and battle-tested shared abstractions for the [broader Rust
|
|
||||||
//! ecosystem][crates.io]. It offers core types, like [`Vec<T>`] and
|
|
||||||
//! [`Option<T>`], library-defined [operations on language
|
|
||||||
//! primitives](#primitives), [standard macros](#macros), [I/O] and
|
|
||||||
//! [multithreading], among [many other things][other].
|
|
||||||
//!
|
|
||||||
//! `std` is available to all Rust crates by default, just as if each one
|
|
||||||
//! contained an `extern crate std;` import at the [crate root]. Therefore the
|
|
||||||
//! standard library can be accessed in [`use`] statements through the path
|
|
||||||
//! `std`, as in [`use std::env`], or in expressions through the absolute path
|
|
||||||
//! `::std`, as in [`::std::env::args`].
|
|
||||||
//!
|
|
||||||
//! # How to read this documentation
|
|
||||||
//!
|
|
||||||
//! If you already know the name of what you are looking for, the fastest way to
|
|
||||||
//! find it is to use the <a href="#" onclick="focusSearchBar();">search
|
|
||||||
//! bar</a> at the top of the page.
|
|
||||||
//!
|
|
||||||
//! Otherwise, you may want to jump to one of these useful sections:
|
|
||||||
//!
|
|
||||||
//! * [`std::*` modules](#modules)
|
|
||||||
//! * [Primitive types](#primitives)
|
|
||||||
//! * [Standard macros](#macros)
|
|
||||||
//! * [The Rust Prelude](prelude/index.html)
|
|
||||||
//!
|
|
||||||
//! If this is your first time, the documentation for the standard library is
|
|
||||||
//! written to be casually perused. Clicking on interesting things should
|
|
||||||
//! generally lead you to interesting places. Still, there are important bits
|
|
||||||
//! you don't want to miss, so read on for a tour of the standard library and
|
|
||||||
//! its documentation!
|
|
||||||
//!
|
|
||||||
//! Once you are familiar with the contents of the standard library you may
|
|
||||||
//! begin to find the verbosity of the prose distracting. At this stage in your
|
|
||||||
//! development you may want to press the `[-]` button near the top of the
|
|
||||||
//! page to collapse it into a more skimmable view.
|
|
||||||
//!
|
|
||||||
//! While you are looking at that `[-]` button also notice the `[src]`
|
|
||||||
//! button. Rust's API documentation comes with the source code and you are
|
|
||||||
//! encouraged to read it. The standard library source is generally high
|
|
||||||
//! quality and a peek behind the curtains is often enlightening.
|
|
||||||
//!
|
|
||||||
//! # What is in the standard library documentation?
|
|
||||||
//!
|
|
||||||
//! First of all, The Rust Standard Library is divided into a number of focused
|
|
||||||
//! modules, [all listed further down this page](#modules). These modules are
|
|
||||||
//! the bedrock upon which all of Rust is forged, and they have mighty names
|
|
||||||
//! like [`std::slice`] and [`std::cmp`]. Modules' documentation typically
|
|
||||||
//! includes an overview of the module along with examples, and are a smart
|
|
||||||
//! place to start familiarizing yourself with the library.
|
|
||||||
//!
|
|
||||||
//! Second, implicit methods on [primitive types] are documented here. This can
|
|
||||||
//! be a source of confusion for two reasons:
|
|
||||||
//!
|
|
||||||
//! 1. While primitives are implemented by the compiler, the standard library
|
|
||||||
//! implements methods directly on the primitive types (and it is the only
|
|
||||||
//! library that does so), which are [documented in the section on
|
|
||||||
//! primitives](#primitives).
|
|
||||||
//! 2. The standard library exports many modules *with the same name as
|
|
||||||
//! primitive types*. These define additional items related to the primitive
|
|
||||||
//! type, but not the all-important methods.
|
|
||||||
//!
|
|
||||||
//! So for example there is a [page for the primitive type
|
|
||||||
//! `i32`](primitive.i32.html) that lists all the methods that can be called on
|
|
||||||
//! 32-bit integers (very useful), and there is a [page for the module
|
|
||||||
//! `std::i32`](i32/index.html) that documents the constant values [`MIN`] and
|
|
||||||
//! [`MAX`](i32/constant.MAX.html) (rarely useful).
|
|
||||||
//!
|
|
||||||
//! Note the documentation for the primitives [`str`] and [`[T]`][slice] (also
|
|
||||||
//! called 'slice'). Many method calls on [`String`] and [`Vec<T>`] are actually
|
|
||||||
//! calls to methods on [`str`] and [`[T]`][slice] respectively, via [deref
|
|
||||||
//! coercions][deref-coercions].
|
|
||||||
//!
|
|
||||||
//! Third, the standard library defines [The Rust Prelude], a small collection
|
|
||||||
//! of items - mostly traits - that are imported into every module of every
|
|
||||||
//! crate. The traits in the prelude are pervasive, making the prelude
|
|
||||||
//! documentation a good entry point to learning about the library.
|
|
||||||
//!
|
|
||||||
//! And finally, the standard library exports a number of standard macros, and
|
|
||||||
//! [lists them on this page](#macros) (technically, not all of the standard
|
|
||||||
//! macros are defined by the standard library - some are defined by the
|
|
||||||
//! compiler - but they are documented here the same). Like the prelude, the
|
|
||||||
//! standard macros are imported by default into all crates.
|
|
||||||
//!
|
|
||||||
//! # Contributing changes to the documentation
|
|
||||||
//!
|
|
||||||
//! Check out the rust contribution guidelines [here](
|
|
||||||
//! https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md).
|
|
||||||
//! The source for this documentation can be found on [Github](https://github.com/rust-lang).
|
|
||||||
//! To contribute changes, make sure you read the guidelines first, then submit
|
|
||||||
//! pull-requests for your suggested changes.
|
|
||||||
//!
|
|
||||||
//! Contributions are appreciated! If you see a part of the docs that can be
|
|
||||||
//! improved, submit a PR, or chat with us first on irc.mozilla.org #rust-docs.
|
|
||||||
//!
|
|
||||||
//! # A Tour of The Rust Standard Library
|
|
||||||
//!
|
|
||||||
//! The rest of this crate documentation is dedicated to pointing out notable
|
|
||||||
//! features of The Rust Standard Library.
|
|
||||||
//!
|
|
||||||
//! ## Containers and collections
|
|
||||||
//!
|
|
||||||
//! The [`option`] and [`result`] modules define optional and error-handling
|
|
||||||
//! types, [`Option<T>`] and [`Result<T, E>`]. The [`iter`] module defines
|
|
||||||
//! Rust's iterator trait, [`Iterator`], which works with the [`for`] loop to
|
|
||||||
//! access collections.
|
|
||||||
//!
|
|
||||||
//! The standard library exposes three common ways to deal with contiguous
|
|
||||||
//! regions of memory:
|
|
||||||
//!
|
|
||||||
//! * [`Vec<T>`] - A heap-allocated *vector* that is resizable at runtime.
|
|
||||||
//! * [`[T; n]`][array] - An inline *array* with a fixed size at compile time.
|
|
||||||
//! * [`[T]`][slice] - A dynamically sized *slice* into any other kind of contiguous
|
|
||||||
//! storage, whether heap-allocated or not.
|
|
||||||
//!
|
|
||||||
//! Slices can only be handled through some kind of *pointer*, and as such come
|
|
||||||
//! in many flavors such as:
|
|
||||||
//!
|
|
||||||
//! * `&[T]` - *shared slice*
|
|
||||||
//! * `&mut [T]` - *mutable slice*
|
|
||||||
//! * [`Box<[T]>`][owned slice] - *owned slice*
|
|
||||||
//!
|
|
||||||
//! [`str`], a UTF-8 string slice, is a primitive type, and the standard library
|
|
||||||
//! defines many methods for it. Rust [`str`]s are typically accessed as
|
|
||||||
//! immutable references: `&str`. Use the owned [`String`] for building and
|
|
||||||
//! mutating strings.
|
|
||||||
//!
|
|
||||||
//! For converting to strings use the [`format!`] macro, and for converting from
|
|
||||||
//! strings use the [`FromStr`] trait.
|
|
||||||
//!
|
|
||||||
//! Data may be shared by placing it in a reference-counted box or the [`Rc`]
|
|
||||||
//! type, and if further contained in a [`Cell`] or [`RefCell`], may be mutated
|
|
||||||
//! as well as shared. Likewise, in a concurrent setting it is common to pair an
|
|
||||||
//! atomically-reference-counted box, [`Arc`], with a [`Mutex`] to get the same
|
|
||||||
//! effect.
|
|
||||||
//!
|
|
||||||
//! The [`collections`] module defines maps, sets, linked lists and other
|
|
||||||
//! typical collection types, including the common [`HashMap<K, V>`].
|
|
||||||
//!
|
|
||||||
//! ## Platform abstractions and I/O
|
|
||||||
//!
|
|
||||||
//! Besides basic data types, the standard library is largely concerned with
|
|
||||||
//! abstracting over differences in common platforms, most notably Windows and
|
|
||||||
//! Unix derivatives.
|
|
||||||
//!
|
|
||||||
//! Common types of I/O, including [files], [TCP], [UDP], are defined in the
|
|
||||||
//! [`io`], [`fs`], and [`net`] modules.
|
|
||||||
//!
|
|
||||||
//! The [`thread`] module contains Rust's threading abstractions. [`sync`]
|
|
||||||
//! contains further primitive shared memory types, including [`atomic`] and
|
|
||||||
//! [`mpsc`], which contains the channel types for message passing.
|
|
||||||
//!
|
|
||||||
//! [I/O]: io/index.html
|
|
||||||
//! [`MIN`]: i32/constant.MIN.html
|
|
||||||
//! [TCP]: net/struct.TcpStream.html
|
|
||||||
//! [The Rust Prelude]: prelude/index.html
|
|
||||||
//! [UDP]: net/struct.UdpSocket.html
|
|
||||||
//! [`::std::env::args`]: env/fn.args.html
|
|
||||||
//! [`Arc`]: sync/struct.Arc.html
|
|
||||||
//! [owned slice]: boxed/index.html
|
|
||||||
//! [`Cell`]: cell/struct.Cell.html
|
|
||||||
//! [`FromStr`]: str/trait.FromStr.html
|
|
||||||
//! [`HashMap<K, V>`]: collections/struct.HashMap.html
|
|
||||||
//! [`Iterator`]: iter/trait.Iterator.html
|
|
||||||
//! [`Mutex`]: sync/struct.Mutex.html
|
|
||||||
//! [`Option<T>`]: option/enum.Option.html
|
|
||||||
//! [`Rc`]: rc/index.html
|
|
||||||
//! [`RefCell`]: cell/struct.RefCell.html
|
|
||||||
//! [`Result<T, E>`]: result/enum.Result.html
|
|
||||||
//! [`String`]: string/struct.String.html
|
|
||||||
//! [`Vec<T>`]: vec/index.html
|
|
||||||
//! [array]: primitive.array.html
|
|
||||||
//! [slice]: primitive.slice.html
|
|
||||||
//! [`atomic`]: sync/atomic/index.html
|
|
||||||
//! [`collections`]: collections/index.html
|
|
||||||
//! [`for`]: ../book/first-edition/loops.html#for
|
|
||||||
//! [`format!`]: macro.format.html
|
|
||||||
//! [`fs`]: fs/index.html
|
|
||||||
//! [`io`]: io/index.html
|
|
||||||
//! [`iter`]: iter/index.html
|
|
||||||
//! [`mpsc`]: sync/mpsc/index.html
|
|
||||||
//! [`net`]: net/index.html
|
|
||||||
//! [`option`]: option/index.html
|
|
||||||
//! [`result`]: result/index.html
|
|
||||||
//! [`std::cmp`]: cmp/index.html
|
|
||||||
//! [`std::slice`]: slice/index.html
|
|
||||||
//! [`str`]: primitive.str.html
|
|
||||||
//! [`sync`]: sync/index.html
|
|
||||||
//! [`thread`]: thread/index.html
|
|
||||||
//! [`use std::env`]: env/index.html
|
|
||||||
//! [`use`]: ../book/first-edition/crates-and-modules.html#importing-modules-with-use
|
|
||||||
//! [crate root]: ../book/first-edition/crates-and-modules.html#basic-terminology-crates-and-modules
|
|
||||||
//! [crates.io]: https://crates.io
|
|
||||||
//! [deref-coercions]: ../book/second-edition/ch15-02-deref.html#implicit-deref-coercions-with-functions-and-methods
|
|
||||||
//! [files]: fs/struct.File.html
|
|
||||||
//! [multithreading]: thread/index.html
|
|
||||||
//! [other]: #what-is-in-the-standard-library-documentation
|
|
||||||
//! [primitive types]: ../book/first-edition/primitive-types.html
|
|
||||||
|
|
||||||
#![stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
|
||||||
html_favicon_url = "https://doc.rust-lang.org/favicon.ico", |
|
||||||
html_root_url = "https://doc.rust-lang.org/nightly/", |
|
||||||
html_playground_url = "https://play.rust-lang.org/", |
|
||||||
issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/", |
|
||||||
test(no_crate_inject, attr(deny(warnings))), |
|
||||||
test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))] |
|
||||||
|
|
||||||
// Don't link to std. We are std.
|
|
||||||
#![no_std] |
|
||||||
|
|
||||||
#![deny(missing_docs)] |
|
||||||
#![deny(missing_debug_implementations)] |
|
||||||
|
|
||||||
// Tell the compiler to link to either panic_abort or panic_unwind
|
|
||||||
#![needs_panic_runtime] |
|
||||||
|
|
||||||
// std may use features in a platform-specific way
|
|
||||||
#![allow(unused_features)] |
|
||||||
|
|
||||||
// std is implemented with unstable features, many of which are internal
|
|
||||||
// compiler details that will never be stable
|
|
||||||
#![cfg_attr(test, feature(test, update_panic_count))] |
|
||||||
#![feature(alloc)] |
|
||||||
#![feature(alloc_error_handler)] |
|
||||||
#![feature(allocator_api)] |
|
||||||
#![feature(allocator_internals)] |
|
||||||
#![feature(allow_internal_unsafe)] |
|
||||||
#![feature(allow_internal_unstable)] |
|
||||||
#![feature(align_offset)] |
|
||||||
#![feature(arbitrary_self_types)] |
|
||||||
#![feature(array_error_internals)] |
|
||||||
#![feature(asm)] |
|
||||||
#![feature(attr_literals)] |
|
||||||
#![feature(box_syntax)] |
|
||||||
#![feature(cfg_target_has_atomic)] |
|
||||||
#![feature(cfg_target_thread_local)] |
|
||||||
#![feature(cfg_target_vendor)] |
|
||||||
#![feature(char_error_internals)] |
|
||||||
#![feature(compiler_builtins_lib)] |
|
||||||
#![feature(const_fn)] |
|
||||||
#![feature(const_int_ops)] |
|
||||||
#![feature(const_ip)] |
|
||||||
#![feature(core_intrinsics)] |
|
||||||
#![feature(dropck_eyepatch)] |
|
||||||
#![feature(exact_size_is_empty)] |
|
||||||
#![feature(external_doc)] |
|
||||||
#![feature(fixed_size_array)] |
|
||||||
#![feature(fn_traits)] |
|
||||||
#![feature(fnbox)] |
|
||||||
#![feature(futures_api)] |
|
||||||
#![feature(generator_trait)] |
|
||||||
#![feature(hashmap_internals)] |
|
||||||
#![feature(int_error_internals)] |
|
||||||
#![feature(integer_atomics)] |
|
||||||
#![feature(lang_items)] |
|
||||||
#![feature(libc)] |
|
||||||
#![feature(link_args)] |
|
||||||
#![feature(linkage)] |
|
||||||
#![feature(macro_vis_matcher)] |
|
||||||
#![feature(needs_panic_runtime)] |
|
||||||
#![feature(never_type)] |
|
||||||
#![cfg_attr(not(stage0), feature(nll))] |
|
||||||
#![feature(exhaustive_patterns)] |
|
||||||
#![feature(on_unimplemented)] |
|
||||||
#![feature(optin_builtin_traits)] |
|
||||||
#![feature(panic_internals)] |
|
||||||
#![feature(panic_unwind)] |
|
||||||
#![feature(pin)] |
|
||||||
#![feature(prelude_import)] |
|
||||||
#![feature(ptr_internals)] |
|
||||||
#![feature(raw)] |
|
||||||
#![feature(rustc_attrs)] |
|
||||||
#![feature(rustc_const_unstable)] |
|
||||||
#![feature(std_internals)] |
|
||||||
#![feature(stdsimd)] |
|
||||||
#![feature(shrink_to)] |
|
||||||
#![feature(slice_concat_ext)] |
|
||||||
#![feature(slice_internals)] |
|
||||||
#![feature(slice_patterns)] |
|
||||||
#![feature(staged_api)] |
|
||||||
#![feature(stmt_expr_attributes)] |
|
||||||
#![feature(str_internals)] |
|
||||||
#![feature(rustc_private)] |
|
||||||
#![feature(thread_local)] |
|
||||||
#![feature(toowned_clone_into)] |
|
||||||
#![feature(try_from)] |
|
||||||
#![feature(try_reserve)] |
|
||||||
#![feature(unboxed_closures)] |
|
||||||
#![feature(untagged_unions)] |
|
||||||
#![feature(unwind_attributes)] |
|
||||||
#![cfg_attr(stage0, feature(use_extern_macros))] |
|
||||||
#![feature(doc_cfg)] |
|
||||||
#![feature(doc_masked)] |
|
||||||
#![feature(doc_spotlight)] |
|
||||||
#![cfg_attr(windows, feature(used))] |
|
||||||
#![feature(doc_alias)] |
|
||||||
#![feature(doc_keyword)] |
|
||||||
#![feature(panic_info_message)] |
|
||||||
#![feature(panic_implementation)] |
|
||||||
#![feature(non_exhaustive)] |
|
||||||
|
|
||||||
#![default_lib_allocator] |
|
||||||
|
|
||||||
// Always use alloc_system during stage0 since we don't know if the alloc_*
|
|
||||||
// crate the stage0 compiler will pick by default is enabled (e.g.
|
|
||||||
// if the user has disabled jemalloc in `./configure`).
|
|
||||||
// `force_alloc_system` is *only* intended as a workaround for local rebuilds
|
|
||||||
// with a rustc without jemalloc.
|
|
||||||
// FIXME(#44236) shouldn't need MSVC logic
|
|
||||||
#[cfg(all(not(target_env = "msvc"),
|
|
||||||
any(all(stage0, not(test)), feature = "force_alloc_system")))] |
|
||||||
#[global_allocator] |
|
||||||
static ALLOC: alloc_system::System = alloc_system::System; |
|
||||||
|
|
||||||
// Explicitly import the prelude. The compiler uses this same unstable attribute
|
|
||||||
// to import the prelude implicitly when building crates that depend on std.
|
|
||||||
#[prelude_import] |
|
||||||
#[allow(unused)] |
|
||||||
use prelude::v1::*; |
|
||||||
|
|
||||||
// Access to Bencher, etc.
|
|
||||||
#[cfg(test)] extern crate test; |
|
||||||
#[cfg(test)] extern crate rand; |
|
||||||
|
|
||||||
// Re-export a few macros from core
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::{assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne}; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::{unreachable, unimplemented, write, writeln, try}; |
|
||||||
|
|
||||||
#[allow(unused_imports)] // macros from `alloc` are not used on all platforms
|
|
||||||
#[macro_use] |
|
||||||
extern crate alloc as alloc_crate; |
|
||||||
extern crate alloc_system; |
|
||||||
#[doc(masked)] |
|
||||||
extern crate libc; |
|
||||||
|
|
||||||
// 3DS-specific dependency
|
|
||||||
extern crate ctru_sys as libctru; |
|
||||||
|
|
||||||
// We always need an unwinder currently for backtraces
|
|
||||||
#[doc(masked)] |
|
||||||
#[allow(unused_extern_crates)] |
|
||||||
extern crate unwind; |
|
||||||
|
|
||||||
// During testing, this crate is not actually the "real" std library, but rather
|
|
||||||
// it links to the real std library, which was compiled from this same source
|
|
||||||
// code. So any lang items std defines are conditionally excluded (or else they
|
|
||||||
// would generate duplicate lang item errors), and any globals it defines are
|
|
||||||
// _not_ the globals used by "real" std. So this import, defined only during
|
|
||||||
// testing gives test-std access to real-std lang items and globals. See #2912
|
|
||||||
#[cfg(test)] extern crate std as realstd; |
|
||||||
|
|
||||||
// The standard macros that are not built-in to the compiler.
|
|
||||||
#[macro_use] |
|
||||||
mod macros; |
|
||||||
|
|
||||||
// The Rust prelude
|
|
||||||
pub mod prelude; |
|
||||||
|
|
||||||
// Public module declarations and re-exports
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::any; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::cell; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::clone; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::cmp; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::convert; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::default; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::hash; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::intrinsics; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::iter; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::marker; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::mem; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::ops; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::ptr; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::raw; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::result; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::option; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::isize; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::i8; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::i16; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::i32; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::i64; |
|
||||||
#[stable(feature = "i128", since = "1.26.0")] |
|
||||||
pub use core::i128; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::usize; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::u8; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::u16; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::u32; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::u64; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use alloc_crate::boxed; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use alloc_crate::rc; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use alloc_crate::borrow; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use alloc_crate::fmt; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use alloc_crate::format; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use alloc_crate::slice; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use alloc_crate::str; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use alloc_crate::string; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use alloc_crate::vec; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::char; |
|
||||||
#[stable(feature = "i128", since = "1.26.0")] |
|
||||||
pub use core::u128; |
|
||||||
#[stable(feature = "core_hint", since = "1.27.0")] |
|
||||||
pub use core::hint; |
|
||||||
|
|
||||||
pub mod f32; |
|
||||||
pub mod f64; |
|
||||||
|
|
||||||
#[macro_use] |
|
||||||
pub mod thread; |
|
||||||
pub mod ascii; |
|
||||||
pub mod collections; |
|
||||||
pub mod env; |
|
||||||
pub mod error; |
|
||||||
pub mod ffi; |
|
||||||
pub mod fs; |
|
||||||
pub mod io; |
|
||||||
pub mod net; |
|
||||||
pub mod num; |
|
||||||
pub mod os; |
|
||||||
pub mod panic; |
|
||||||
pub mod path; |
|
||||||
pub mod process; |
|
||||||
pub mod sync; |
|
||||||
pub mod time; |
|
||||||
|
|
||||||
#[unstable(feature = "futures_api",
|
|
||||||
reason = "futures in libcore are unstable", |
|
||||||
issue = "50547")] |
|
||||||
pub mod task { |
|
||||||
//! Types and Traits for working with asynchronous tasks.
|
|
||||||
#[doc(inline)] |
|
||||||
pub use core::task::*; |
|
||||||
#[doc(inline)] |
|
||||||
pub use alloc_crate::task::*; |
|
||||||
} |
|
||||||
|
|
||||||
#[unstable(feature = "futures_api",
|
|
||||||
reason = "futures in libcore are unstable", |
|
||||||
issue = "50547")] |
|
||||||
pub mod future; |
|
||||||
|
|
||||||
// Platform-abstraction modules
|
|
||||||
#[macro_use] |
|
||||||
mod sys_common; |
|
||||||
mod sys; |
|
||||||
|
|
||||||
pub mod alloc; |
|
||||||
|
|
||||||
// Private support modules
|
|
||||||
mod panicking; |
|
||||||
mod memchr; |
|
||||||
|
|
||||||
// The runtime entry point and a few unstable public functions used by the
|
|
||||||
// compiler
|
|
||||||
pub mod rt; |
|
||||||
|
|
||||||
// Include a number of private modules that exist solely to provide
|
|
||||||
// the rustdoc documentation for primitive types. Using `include!`
|
|
||||||
// because rustdoc only looks for these modules at the crate level.
|
|
||||||
include!("primitive_docs.rs"); |
|
||||||
|
|
||||||
// Include a number of private modules that exist solely to provide
|
|
||||||
// the rustdoc documentation for the existing keywords. Using `include!`
|
|
||||||
// because rustdoc only looks for these modules at the crate level.
|
|
||||||
include!("keyword_docs.rs"); |
|
@ -1,871 +0,0 @@ |
|||||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Standard library macros
|
|
||||||
//!
|
|
||||||
//! This modules contains a set of macros which are exported from the standard
|
|
||||||
//! library. Each macro is available for use when linking against the standard
|
|
||||||
//! library.
|
|
||||||
|
|
||||||
/// The entry point for panic of Rust threads.
|
|
||||||
///
|
|
||||||
/// This allows a program to to terminate immediately and provide feedback
|
|
||||||
/// to the caller of the program. `panic!` should be used when a program reaches
|
|
||||||
/// an unrecoverable problem.
|
|
||||||
///
|
|
||||||
/// This macro is the perfect way to assert conditions in example code and in
|
|
||||||
/// tests. `panic!` is closely tied with the `unwrap` method of both [`Option`]
|
|
||||||
/// and [`Result`][runwrap] enums. Both implementations call `panic!` when they are set
|
|
||||||
/// to None or Err variants.
|
|
||||||
///
|
|
||||||
/// This macro is used to inject panic into a Rust thread, causing the thread to
|
|
||||||
/// panic entirely. Each thread's panic can be reaped as the `Box<Any>` type,
|
|
||||||
/// and the single-argument form of the `panic!` macro will be the value which
|
|
||||||
/// is transmitted.
|
|
||||||
///
|
|
||||||
/// [`Result`] enum is often a better solution for recovering from errors than
|
|
||||||
/// using the `panic!` macro. This macro should be used to avoid proceeding using
|
|
||||||
/// incorrect values, such as from external sources. Detailed information about
|
|
||||||
/// error handling is found in the [book].
|
|
||||||
///
|
|
||||||
/// The multi-argument form of this macro panics with a string and has the
|
|
||||||
/// [`format!`] syntax for building a string.
|
|
||||||
///
|
|
||||||
/// See also the macro [`compile_error!`], for raising errors during compilation.
|
|
||||||
///
|
|
||||||
/// [runwrap]: ../std/result/enum.Result.html#method.unwrap
|
|
||||||
/// [`Option`]: ../std/option/enum.Option.html#method.unwrap
|
|
||||||
/// [`Result`]: ../std/result/enum.Result.html
|
|
||||||
/// [`format!`]: ../std/macro.format.html
|
|
||||||
/// [`compile_error!`]: ../std/macro.compile_error.html
|
|
||||||
/// [book]: ../book/second-edition/ch09-01-unrecoverable-errors-with-panic.html
|
|
||||||
///
|
|
||||||
/// # Current implementation
|
|
||||||
///
|
|
||||||
/// If the main thread panics it will terminate all your threads and end your
|
|
||||||
/// program with code `101`.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```should_panic
|
|
||||||
/// # #![allow(unreachable_code)]
|
|
||||||
/// panic!();
|
|
||||||
/// panic!("this is a terrible mistake!");
|
|
||||||
/// panic!(4); // panic with the value of 4 to be collected elsewhere
|
|
||||||
/// panic!("this is a {} {message}", "fancy", message = "message");
|
|
||||||
/// ```
|
|
||||||
#[macro_export] |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#[allow_internal_unstable] |
|
||||||
macro_rules! panic { |
|
||||||
() => ({ |
|
||||||
panic!("explicit panic") |
|
||||||
}); |
|
||||||
($msg:expr) => ({ |
|
||||||
$crate::rt::begin_panic($msg, &(file!(), line!(), __rust_unstable_column!())) |
|
||||||
}); |
|
||||||
($msg:expr,) => ({ |
|
||||||
panic!($msg) |
|
||||||
}); |
|
||||||
($fmt:expr, $($arg:tt)+) => ({ |
|
||||||
$crate::rt::begin_panic_fmt(&format_args!($fmt, $($arg)+), |
|
||||||
&(file!(), line!(), __rust_unstable_column!())) |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
/// Macro for printing to the standard output.
|
|
||||||
///
|
|
||||||
/// Equivalent to the [`println!`] macro except that a newline is not printed at
|
|
||||||
/// the end of the message.
|
|
||||||
///
|
|
||||||
/// Note that stdout is frequently line-buffered by default so it may be
|
|
||||||
/// necessary to use [`io::stdout().flush()`][flush] to ensure the output is emitted
|
|
||||||
/// immediately.
|
|
||||||
///
|
|
||||||
/// Use `print!` only for the primary output of your program. Use
|
|
||||||
/// [`eprint!`] instead to print error and progress messages.
|
|
||||||
///
|
|
||||||
/// [`println!`]: ../std/macro.println.html
|
|
||||||
/// [flush]: ../std/io/trait.Write.html#tymethod.flush
|
|
||||||
/// [`eprint!`]: ../std/macro.eprint.html
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// Panics if writing to `io::stdout()` fails.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::io::{self, Write};
|
|
||||||
///
|
|
||||||
/// print!("this ");
|
|
||||||
/// print!("will ");
|
|
||||||
/// print!("be ");
|
|
||||||
/// print!("on ");
|
|
||||||
/// print!("the ");
|
|
||||||
/// print!("same ");
|
|
||||||
/// print!("line ");
|
|
||||||
///
|
|
||||||
/// io::stdout().flush().unwrap();
|
|
||||||
///
|
|
||||||
/// print!("this string has a newline, why not choose println! instead?\n");
|
|
||||||
///
|
|
||||||
/// io::stdout().flush().unwrap();
|
|
||||||
/// ```
|
|
||||||
#[macro_export] |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#[allow_internal_unstable] |
|
||||||
macro_rules! print { |
|
||||||
($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*))); |
|
||||||
} |
|
||||||
|
|
||||||
/// Macro for printing to the standard output, with a newline.
|
|
||||||
///
|
|
||||||
/// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
|
|
||||||
/// (no additional CARRIAGE RETURN (`\r`/`U+000D`).
|
|
||||||
///
|
|
||||||
/// Use the [`format!`] syntax to write data to the standard output.
|
|
||||||
/// See [`std::fmt`] for more information.
|
|
||||||
///
|
|
||||||
/// Use `println!` only for the primary output of your program. Use
|
|
||||||
/// [`eprintln!`] instead to print error and progress messages.
|
|
||||||
///
|
|
||||||
/// [`format!`]: ../std/macro.format.html
|
|
||||||
/// [`std::fmt`]: ../std/fmt/index.html
|
|
||||||
/// [`eprintln!`]: ../std/macro.eprint.html
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// Panics if writing to `io::stdout` fails.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// println!(); // prints just a newline
|
|
||||||
/// println!("hello there!");
|
|
||||||
/// println!("format {} arguments", "some");
|
|
||||||
/// ```
|
|
||||||
#[macro_export] |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#[allow_internal_unstable] |
|
||||||
macro_rules! println { |
|
||||||
() => (print!("\n")); |
|
||||||
($($arg:tt)*) => ({ |
|
||||||
$crate::io::_print(format_args_nl!($($arg)*)); |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
/// Macro for printing to the standard error.
|
|
||||||
///
|
|
||||||
/// Equivalent to the [`print!`] macro, except that output goes to
|
|
||||||
/// [`io::stderr`] instead of `io::stdout`. See [`print!`] for
|
|
||||||
/// example usage.
|
|
||||||
///
|
|
||||||
/// Use `eprint!` only for error and progress messages. Use `print!`
|
|
||||||
/// instead for the primary output of your program.
|
|
||||||
///
|
|
||||||
/// [`io::stderr`]: ../std/io/struct.Stderr.html
|
|
||||||
/// [`print!`]: ../std/macro.print.html
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// Panics if writing to `io::stderr` fails.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// eprint!("Error: Could not complete task");
|
|
||||||
/// ```
|
|
||||||
#[macro_export] |
|
||||||
#[stable(feature = "eprint", since = "1.19.0")] |
|
||||||
#[allow_internal_unstable] |
|
||||||
macro_rules! eprint { |
|
||||||
($($arg:tt)*) => ($crate::io::_eprint(format_args!($($arg)*))); |
|
||||||
} |
|
||||||
|
|
||||||
/// Macro for printing to the standard error, with a newline.
|
|
||||||
///
|
|
||||||
/// Equivalent to the [`println!`] macro, except that output goes to
|
|
||||||
/// [`io::stderr`] instead of `io::stdout`. See [`println!`] for
|
|
||||||
/// example usage.
|
|
||||||
///
|
|
||||||
/// Use `eprintln!` only for error and progress messages. Use `println!`
|
|
||||||
/// instead for the primary output of your program.
|
|
||||||
///
|
|
||||||
/// [`io::stderr`]: ../std/io/struct.Stderr.html
|
|
||||||
/// [`println!`]: ../std/macro.println.html
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// Panics if writing to `io::stderr` fails.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// eprintln!("Error: Could not complete task");
|
|
||||||
/// ```
|
|
||||||
#[macro_export] |
|
||||||
#[stable(feature = "eprint", since = "1.19.0")] |
|
||||||
#[allow_internal_unstable] |
|
||||||
macro_rules! eprintln { |
|
||||||
() => (eprint!("\n")); |
|
||||||
($($arg:tt)*) => ({ |
|
||||||
$crate::io::_eprint(format_args_nl!($($arg)*)); |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
#[macro_export] |
|
||||||
#[unstable(feature = "await_macro", issue = "50547")] |
|
||||||
#[allow_internal_unstable] |
|
||||||
#[allow_internal_unsafe] |
|
||||||
macro_rules! await { |
|
||||||
($e:expr) => { { |
|
||||||
let mut pinned = $e; |
|
||||||
loop { |
|
||||||
if let $crate::task::Poll::Ready(x) = |
|
||||||
$crate::future::poll_in_task_cx(unsafe { |
|
||||||
$crate::mem::PinMut::new_unchecked(&mut pinned) |
|
||||||
}) |
|
||||||
{ |
|
||||||
break x; |
|
||||||
} |
|
||||||
// FIXME(cramertj) prior to stabilizing await, we have to ensure that this
|
|
||||||
// can't be used to create a generator on stable via `|| await!()`.
|
|
||||||
yield |
|
||||||
} |
|
||||||
} } |
|
||||||
} |
|
||||||
|
|
||||||
/// A macro to select an event from a number of receivers.
|
|
||||||
///
|
|
||||||
/// This macro is used to wait for the first event to occur on a number of
|
|
||||||
/// receivers. It places no restrictions on the types of receivers given to
|
|
||||||
/// this macro, this can be viewed as a heterogeneous select.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// #![feature(mpsc_select)]
|
|
||||||
///
|
|
||||||
/// use std::thread;
|
|
||||||
/// use std::sync::mpsc;
|
|
||||||
///
|
|
||||||
/// // two placeholder functions for now
|
|
||||||
/// fn long_running_thread() {}
|
|
||||||
/// fn calculate_the_answer() -> u32 { 42 }
|
|
||||||
///
|
|
||||||
/// let (tx1, rx1) = mpsc::channel();
|
|
||||||
/// let (tx2, rx2) = mpsc::channel();
|
|
||||||
///
|
|
||||||
/// thread::spawn(move|| { long_running_thread(); tx1.send(()).unwrap(); });
|
|
||||||
/// thread::spawn(move|| { tx2.send(calculate_the_answer()).unwrap(); });
|
|
||||||
///
|
|
||||||
/// select! {
|
|
||||||
/// _ = rx1.recv() => println!("the long running thread finished first"),
|
|
||||||
/// answer = rx2.recv() => {
|
|
||||||
/// println!("the answer was: {}", answer.unwrap());
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
/// # drop(rx1.recv());
|
|
||||||
/// # drop(rx2.recv());
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// For more information about select, see the `std::sync::mpsc::Select` structure.
|
|
||||||
#[macro_export] |
|
||||||
#[unstable(feature = "mpsc_select", issue = "27800")] |
|
||||||
macro_rules! select { |
|
||||||
( |
|
||||||
$($name:pat = $rx:ident.$meth:ident() => $code:expr),+ |
|
||||||
) => ({ |
|
||||||
use $crate::sync::mpsc::Select; |
|
||||||
let sel = Select::new(); |
|
||||||
$( let mut $rx = sel.handle(&$rx); )+ |
|
||||||
unsafe { |
|
||||||
$( $rx.add(); )+ |
|
||||||
} |
|
||||||
let ret = sel.wait(); |
|
||||||
$( if ret == $rx.id() { let $name = $rx.$meth(); $code } else )+ |
|
||||||
{ unreachable!() } |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(test)] |
|
||||||
macro_rules! assert_approx_eq { |
|
||||||
($a:expr, $b:expr) => ({ |
|
||||||
let (a, b) = (&$a, &$b); |
|
||||||
assert!((*a - *b).abs() < 1.0e-6, |
|
||||||
"{} is not approximately equal to {}", *a, *b); |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
/// Built-in macros to the compiler itself.
|
|
||||||
///
|
|
||||||
/// These macros do not have any corresponding definition with a `macro_rules!`
|
|
||||||
/// macro, but are documented here. Their implementations can be found hardcoded
|
|
||||||
/// into libsyntax itself.
|
|
||||||
#[cfg(dox)] |
|
||||||
mod builtin { |
|
||||||
|
|
||||||
/// Unconditionally causes compilation to fail with the given error message when encountered.
|
|
||||||
///
|
|
||||||
/// This macro should be used when a crate uses a conditional compilation strategy to provide
|
|
||||||
/// better error messages for erroneous conditions. It's the compiler-level form of [`panic!`],
|
|
||||||
/// which emits an error at *runtime*, rather than during compilation.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// Two such examples are macros and `#[cfg]` environments.
|
|
||||||
///
|
|
||||||
/// Emit better compiler error if a macro is passed invalid values. Without the final branch,
|
|
||||||
/// the compiler would still emit an error, but the error's message would not mention the two
|
|
||||||
/// valid values.
|
|
||||||
///
|
|
||||||
/// ```compile_fail
|
|
||||||
/// macro_rules! give_me_foo_or_bar {
|
|
||||||
/// (foo) => {};
|
|
||||||
/// (bar) => {};
|
|
||||||
/// ($x:ident) => {
|
|
||||||
/// compile_error!("This macro only accepts `foo` or `bar`");
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// give_me_foo_or_bar!(neither);
|
|
||||||
/// // ^ will fail at compile time with message "This macro only accepts `foo` or `bar`"
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Emit compiler error if one of a number of features isn't available.
|
|
||||||
///
|
|
||||||
/// ```compile_fail
|
|
||||||
/// #[cfg(not(any(feature = "foo", feature = "bar")))]
|
|
||||||
/// compile_error!("Either feature \"foo\" or \"bar\" must be enabled for this crate.")
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// [`panic!`]: ../std/macro.panic.html
|
|
||||||
#[stable(feature = "compile_error_macro", since = "1.20.0")] |
|
||||||
#[rustc_doc_only_macro] |
|
||||||
macro_rules! compile_error { |
|
||||||
($msg:expr) => ({ /* compiler built-in */ }); |
|
||||||
($msg:expr,) => ({ /* compiler built-in */ }); |
|
||||||
} |
|
||||||
|
|
||||||
/// The core macro for formatted string creation & output.
|
|
||||||
///
|
|
||||||
/// This macro functions by taking a formatting string literal containing
|
|
||||||
/// `{}` for each additional argument passed. `format_args!` prepares the
|
|
||||||
/// additional parameters to ensure the output can be interpreted as a string
|
|
||||||
/// and canonicalizes the arguments into a single type. Any value that implements
|
|
||||||
/// the [`Display`] trait can be passed to `format_args!`, as can any
|
|
||||||
/// [`Debug`] implementation be passed to a `{:?}` within the formatting string.
|
|
||||||
///
|
|
||||||
/// This macro produces a value of type [`fmt::Arguments`]. This value can be
|
|
||||||
/// passed to the macros within [`std::fmt`] for performing useful redirection.
|
|
||||||
/// All other formatting macros ([`format!`], [`write!`], [`println!`], etc) are
|
|
||||||
/// proxied through this one. `format_args!`, unlike its derived macros, avoids
|
|
||||||
/// heap allocations.
|
|
||||||
///
|
|
||||||
/// You can use the [`fmt::Arguments`] value that `format_args!` returns
|
|
||||||
/// in `Debug` and `Display` contexts as seen below. The example also shows
|
|
||||||
/// that `Debug` and `Display` format to the same thing: the interpolated
|
|
||||||
/// format string in `format_args!`.
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// let debug = format!("{:?}", format_args!("{} foo {:?}", 1, 2));
|
|
||||||
/// let display = format!("{}", format_args!("{} foo {:?}", 1, 2));
|
|
||||||
/// assert_eq!("1 foo 2", display);
|
|
||||||
/// assert_eq!(display, debug);
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// For more information, see the documentation in [`std::fmt`].
|
|
||||||
///
|
|
||||||
/// [`Display`]: ../std/fmt/trait.Display.html
|
|
||||||
/// [`Debug`]: ../std/fmt/trait.Debug.html
|
|
||||||
/// [`fmt::Arguments`]: ../std/fmt/struct.Arguments.html
|
|
||||||
/// [`std::fmt`]: ../std/fmt/index.html
|
|
||||||
/// [`format!`]: ../std/macro.format.html
|
|
||||||
/// [`write!`]: ../std/macro.write.html
|
|
||||||
/// [`println!`]: ../std/macro.println.html
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::fmt;
|
|
||||||
///
|
|
||||||
/// let s = fmt::format(format_args!("hello {}", "world"));
|
|
||||||
/// assert_eq!(s, format!("hello {}", "world"));
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#[rustc_doc_only_macro] |
|
||||||
macro_rules! format_args { |
|
||||||
($fmt:expr) => ({ /* compiler built-in */ }); |
|
||||||
($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ }); |
|
||||||
} |
|
||||||
|
|
||||||
/// Inspect an environment variable at compile time.
|
|
||||||
///
|
|
||||||
/// This macro will expand to the value of the named environment variable at
|
|
||||||
/// compile time, yielding an expression of type `&'static str`.
|
|
||||||
///
|
|
||||||
/// If the environment variable is not defined, then a compilation error
|
|
||||||
/// will be emitted. To not emit a compile error, use the [`option_env!`]
|
|
||||||
/// macro instead.
|
|
||||||
///
|
|
||||||
/// [`option_env!`]: ../std/macro.option_env.html
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// let path: &'static str = env!("PATH");
|
|
||||||
/// println!("the $PATH variable at the time of compiling was: {}", path);
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// You can customize the error message by passing a string as the second
|
|
||||||
/// parameter:
|
|
||||||
///
|
|
||||||
/// ```compile_fail
|
|
||||||
/// let doc: &'static str = env!("documentation", "what's that?!");
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// If the `documentation` environment variable is not defined, you'll get
|
|
||||||
/// the following error:
|
|
||||||
///
|
|
||||||
/// ```text
|
|
||||||
/// error: what's that?!
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#[rustc_doc_only_macro] |
|
||||||
macro_rules! env { |
|
||||||
($name:expr) => ({ /* compiler built-in */ }); |
|
||||||
($name:expr,) => ({ /* compiler built-in */ }); |
|
||||||
} |
|
||||||
|
|
||||||
/// Optionally inspect an environment variable at compile time.
|
|
||||||
///
|
|
||||||
/// If the named environment variable is present at compile time, this will
|
|
||||||
/// expand into an expression of type `Option<&'static str>` whose value is
|
|
||||||
/// `Some` of the value of the environment variable. If the environment
|
|
||||||
/// variable is not present, then this will expand to `None`. See
|
|
||||||
/// [`Option<T>`][option] for more information on this type.
|
|
||||||
///
|
|
||||||
/// A compile time error is never emitted when using this macro regardless
|
|
||||||
/// of whether the environment variable is present or not.
|
|
||||||
///
|
|
||||||
/// [option]: ../std/option/enum.Option.html
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// let key: Option<&'static str> = option_env!("SECRET_KEY");
|
|
||||||
/// println!("the secret key might be: {:?}", key);
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#[rustc_doc_only_macro] |
|
||||||
macro_rules! option_env { |
|
||||||
($name:expr) => ({ /* compiler built-in */ }); |
|
||||||
($name:expr,) => ({ /* compiler built-in */ }); |
|
||||||
} |
|
||||||
|
|
||||||
/// Concatenate identifiers into one identifier.
|
|
||||||
///
|
|
||||||
/// This macro takes any number of comma-separated identifiers, and
|
|
||||||
/// concatenates them all into one, yielding an expression which is a new
|
|
||||||
/// identifier. Note that hygiene makes it such that this macro cannot
|
|
||||||
/// capture local variables. Also, as a general rule, macros are only
|
|
||||||
/// allowed in item, statement or expression position. That means while
|
|
||||||
/// you may use this macro for referring to existing variables, functions or
|
|
||||||
/// modules etc, you cannot define a new one with it.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// #![feature(concat_idents)]
|
|
||||||
///
|
|
||||||
/// # fn main() {
|
|
||||||
/// fn foobar() -> u32 { 23 }
|
|
||||||
///
|
|
||||||
/// let f = concat_idents!(foo, bar);
|
|
||||||
/// println!("{}", f());
|
|
||||||
///
|
|
||||||
/// // fn concat_idents!(new, fun, name) { } // not usable in this way!
|
|
||||||
/// # }
|
|
||||||
/// ```
|
|
||||||
#[unstable(feature = "concat_idents_macro", issue = "29599")] |
|
||||||
#[rustc_doc_only_macro] |
|
||||||
macro_rules! concat_idents { |
|
||||||
($($e:ident),+) => ({ /* compiler built-in */ }); |
|
||||||
($($e:ident,)+) => ({ /* compiler built-in */ }); |
|
||||||
} |
|
||||||
|
|
||||||
/// Concatenates literals into a static string slice.
|
|
||||||
///
|
|
||||||
/// This macro takes any number of comma-separated literals, yielding an
|
|
||||||
/// expression of type `&'static str` which represents all of the literals
|
|
||||||
/// concatenated left-to-right.
|
|
||||||
///
|
|
||||||
/// Integer and floating point literals are stringified in order to be
|
|
||||||
/// concatenated.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// let s = concat!("test", 10, 'b', true);
|
|
||||||
/// assert_eq!(s, "test10btrue");
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#[rustc_doc_only_macro] |
|
||||||
macro_rules! concat { |
|
||||||
($($e:expr),*) => ({ /* compiler built-in */ }); |
|
||||||
($($e:expr,)*) => ({ /* compiler built-in */ }); |
|
||||||
} |
|
||||||
|
|
||||||
/// A macro which expands to the line number on which it was invoked.
|
|
||||||
///
|
|
||||||
/// With [`column!`] and [`file!`], these macros provide debugging information for
|
|
||||||
/// developers about the location within the source.
|
|
||||||
///
|
|
||||||
/// The expanded expression has type `u32` and is 1-based, so the first line
|
|
||||||
/// in each file evaluates to 1, the second to 2, etc. This is consistent
|
|
||||||
/// with error messages by common compilers or popular editors.
|
|
||||||
/// The returned line is *not necessarily* the line of the `line!` invocation itself,
|
|
||||||
/// but rather the first macro invocation leading up to the invocation
|
|
||||||
/// of the `line!` macro.
|
|
||||||
///
|
|
||||||
/// [`column!`]: macro.column.html
|
|
||||||
/// [`file!`]: macro.file.html
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// let current_line = line!();
|
|
||||||
/// println!("defined on line: {}", current_line);
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#[rustc_doc_only_macro] |
|
||||||
macro_rules! line { () => ({ /* compiler built-in */ }) } |
|
||||||
|
|
||||||
/// A macro which expands to the column number on which it was invoked.
|
|
||||||
///
|
|
||||||
/// With [`line!`] and [`file!`], these macros provide debugging information for
|
|
||||||
/// developers about the location within the source.
|
|
||||||
///
|
|
||||||
/// The expanded expression has type `u32` and is 1-based, so the first column
|
|
||||||
/// in each line evaluates to 1, the second to 2, etc. This is consistent
|
|
||||||
/// with error messages by common compilers or popular editors.
|
|
||||||
/// The returned column is *not necessarily* the line of the `column!` invocation itself,
|
|
||||||
/// but rather the first macro invocation leading up to the invocation
|
|
||||||
/// of the `column!` macro.
|
|
||||||
///
|
|
||||||
/// [`line!`]: macro.line.html
|
|
||||||
/// [`file!`]: macro.file.html
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// let current_col = column!();
|
|
||||||
/// println!("defined on column: {}", current_col);
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#[rustc_doc_only_macro] |
|
||||||
macro_rules! column { () => ({ /* compiler built-in */ }) } |
|
||||||
|
|
||||||
/// A macro which expands to the file name from which it was invoked.
|
|
||||||
///
|
|
||||||
/// With [`line!`] and [`column!`], these macros provide debugging information for
|
|
||||||
/// developers about the location within the source.
|
|
||||||
///
|
|
||||||
///
|
|
||||||
/// The expanded expression has type `&'static str`, and the returned file
|
|
||||||
/// is not the invocation of the `file!` macro itself, but rather the
|
|
||||||
/// first macro invocation leading up to the invocation of the `file!`
|
|
||||||
/// macro.
|
|
||||||
///
|
|
||||||
/// [`line!`]: macro.line.html
|
|
||||||
/// [`column!`]: macro.column.html
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// let this_file = file!();
|
|
||||||
/// println!("defined in file: {}", this_file);
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#[rustc_doc_only_macro] |
|
||||||
macro_rules! file { () => ({ /* compiler built-in */ }) } |
|
||||||
|
|
||||||
/// A macro which stringifies its arguments.
|
|
||||||
///
|
|
||||||
/// This macro will yield an expression of type `&'static str` which is the
|
|
||||||
/// stringification of all the tokens passed to the macro. No restrictions
|
|
||||||
/// are placed on the syntax of the macro invocation itself.
|
|
||||||
///
|
|
||||||
/// Note that the expanded results of the input tokens may change in the
|
|
||||||
/// future. You should be careful if you rely on the output.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// let one_plus_one = stringify!(1 + 1);
|
|
||||||
/// assert_eq!(one_plus_one, "1 + 1");
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#[rustc_doc_only_macro] |
|
||||||
macro_rules! stringify { ($($t:tt)*) => ({ /* compiler built-in */ }) } |
|
||||||
|
|
||||||
/// Includes a utf8-encoded file as a string.
|
|
||||||
///
|
|
||||||
/// The file is located relative to the current file. (similarly to how
|
|
||||||
/// modules are found)
|
|
||||||
///
|
|
||||||
/// This macro will yield an expression of type `&'static str` which is the
|
|
||||||
/// contents of the file.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// Assume there are two files in the same directory with the following
|
|
||||||
/// contents:
|
|
||||||
///
|
|
||||||
/// File 'spanish.in':
|
|
||||||
///
|
|
||||||
/// ```text
|
|
||||||
/// adiós
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// File 'main.rs':
|
|
||||||
///
|
|
||||||
/// ```ignore (cannot-doctest-external-file-dependency)
|
|
||||||
/// fn main() {
|
|
||||||
/// let my_str = include_str!("spanish.in");
|
|
||||||
/// assert_eq!(my_str, "adiós\n");
|
|
||||||
/// print!("{}", my_str);
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Compiling 'main.rs' and running the resulting binary will print "adiós".
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#[rustc_doc_only_macro] |
|
||||||
macro_rules! include_str { |
|
||||||
($file:expr) => ({ /* compiler built-in */ }); |
|
||||||
($file:expr,) => ({ /* compiler built-in */ }); |
|
||||||
} |
|
||||||
|
|
||||||
/// Includes a file as a reference to a byte array.
|
|
||||||
///
|
|
||||||
/// The file is located relative to the current file. (similarly to how
|
|
||||||
/// modules are found)
|
|
||||||
///
|
|
||||||
/// This macro will yield an expression of type `&'static [u8; N]` which is
|
|
||||||
/// the contents of the file.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// Assume there are two files in the same directory with the following
|
|
||||||
/// contents:
|
|
||||||
///
|
|
||||||
/// File 'spanish.in':
|
|
||||||
///
|
|
||||||
/// ```text
|
|
||||||
/// adiós
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// File 'main.rs':
|
|
||||||
///
|
|
||||||
/// ```ignore (cannot-doctest-external-file-dependency)
|
|
||||||
/// fn main() {
|
|
||||||
/// let bytes = include_bytes!("spanish.in");
|
|
||||||
/// assert_eq!(bytes, b"adi\xc3\xb3s\n");
|
|
||||||
/// print!("{}", String::from_utf8_lossy(bytes));
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Compiling 'main.rs' and running the resulting binary will print "adiós".
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#[rustc_doc_only_macro] |
|
||||||
macro_rules! include_bytes { |
|
||||||
($file:expr) => ({ /* compiler built-in */ }); |
|
||||||
($file:expr,) => ({ /* compiler built-in */ }); |
|
||||||
} |
|
||||||
|
|
||||||
/// Expands to a string that represents the current module path.
|
|
||||||
///
|
|
||||||
/// The current module path can be thought of as the hierarchy of modules
|
|
||||||
/// leading back up to the crate root. The first component of the path
|
|
||||||
/// returned is the name of the crate currently being compiled.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// mod test {
|
|
||||||
/// pub fn foo() {
|
|
||||||
/// assert!(module_path!().ends_with("test"));
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// test::foo();
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#[rustc_doc_only_macro] |
|
||||||
macro_rules! module_path { () => ({ /* compiler built-in */ }) } |
|
||||||
|
|
||||||
/// Boolean evaluation of configuration flags, at compile-time.
|
|
||||||
///
|
|
||||||
/// In addition to the `#[cfg]` attribute, this macro is provided to allow
|
|
||||||
/// boolean expression evaluation of configuration flags. This frequently
|
|
||||||
/// leads to less duplicated code.
|
|
||||||
///
|
|
||||||
/// The syntax given to this macro is the same syntax as [the `cfg`
|
|
||||||
/// attribute](../book/first-edition/conditional-compilation.html).
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// let my_directory = if cfg!(windows) {
|
|
||||||
/// "windows-specific-directory"
|
|
||||||
/// } else {
|
|
||||||
/// "unix-directory"
|
|
||||||
/// };
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#[rustc_doc_only_macro] |
|
||||||
macro_rules! cfg { ($($cfg:tt)*) => ({ /* compiler built-in */ }) } |
|
||||||
|
|
||||||
/// Parse a file as an expression or an item according to the context.
|
|
||||||
///
|
|
||||||
/// The file is located relative to the current file (similarly to how
|
|
||||||
/// modules are found).
|
|
||||||
///
|
|
||||||
/// Using this macro is often a bad idea, because if the file is
|
|
||||||
/// parsed as an expression, it is going to be placed in the
|
|
||||||
/// surrounding code unhygienically. This could result in variables
|
|
||||||
/// or functions being different from what the file expected if
|
|
||||||
/// there are variables or functions that have the same name in
|
|
||||||
/// the current file.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// Assume there are two files in the same directory with the following
|
|
||||||
/// contents:
|
|
||||||
///
|
|
||||||
/// File 'monkeys.in':
|
|
||||||
///
|
|
||||||
/// ```ignore (only-for-syntax-highlight)
|
|
||||||
/// ['🙈', '🙊', '🙉']
|
|
||||||
/// .iter()
|
|
||||||
/// .cycle()
|
|
||||||
/// .take(6)
|
|
||||||
/// .collect::<String>()
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// File 'main.rs':
|
|
||||||
///
|
|
||||||
/// ```ignore (cannot-doctest-external-file-dependency)
|
|
||||||
/// fn main() {
|
|
||||||
/// let my_string = include!("monkeys.in");
|
|
||||||
/// assert_eq!("🙈🙊🙉🙈🙊🙉", my_string);
|
|
||||||
/// println!("{}", my_string);
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Compiling 'main.rs' and running the resulting binary will print
|
|
||||||
/// "🙈🙊🙉🙈🙊🙉".
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#[rustc_doc_only_macro] |
|
||||||
macro_rules! include { |
|
||||||
($file:expr) => ({ /* compiler built-in */ }); |
|
||||||
($file:expr,) => ({ /* compiler built-in */ }); |
|
||||||
} |
|
||||||
|
|
||||||
/// Ensure that a boolean expression is `true` at runtime.
|
|
||||||
///
|
|
||||||
/// This will invoke the [`panic!`] macro if the provided expression cannot be
|
|
||||||
/// evaluated to `true` at runtime.
|
|
||||||
///
|
|
||||||
/// # Uses
|
|
||||||
///
|
|
||||||
/// Assertions are always checked in both debug and release builds, and cannot
|
|
||||||
/// be disabled. See [`debug_assert!`] for assertions that are not enabled in
|
|
||||||
/// release builds by default.
|
|
||||||
///
|
|
||||||
/// Unsafe code relies on `assert!` to enforce run-time invariants that, if
|
|
||||||
/// violated could lead to unsafety.
|
|
||||||
///
|
|
||||||
/// Other use-cases of `assert!` include [testing] and enforcing run-time
|
|
||||||
/// invariants in safe code (whose violation cannot result in unsafety).
|
|
||||||
///
|
|
||||||
/// # Custom Messages
|
|
||||||
///
|
|
||||||
/// This macro has a second form, where a custom panic message can
|
|
||||||
/// be provided with or without arguments for formatting. See [`std::fmt`]
|
|
||||||
/// for syntax for this form.
|
|
||||||
///
|
|
||||||
/// [`panic!`]: macro.panic.html
|
|
||||||
/// [`debug_assert!`]: macro.debug_assert.html
|
|
||||||
/// [testing]: ../book/second-edition/ch11-01-writing-tests.html#checking-results-with-the-assert-macro
|
|
||||||
/// [`std::fmt`]: ../std/fmt/index.html
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// // the panic message for these assertions is the stringified value of the
|
|
||||||
/// // expression given.
|
|
||||||
/// assert!(true);
|
|
||||||
///
|
|
||||||
/// fn some_computation() -> bool { true } // a very simple function
|
|
||||||
///
|
|
||||||
/// assert!(some_computation());
|
|
||||||
///
|
|
||||||
/// // assert with a custom message
|
|
||||||
/// let x = true;
|
|
||||||
/// assert!(x, "x wasn't true!");
|
|
||||||
///
|
|
||||||
/// let a = 3; let b = 27;
|
|
||||||
/// assert!(a + b == 30, "a = {}, b = {}", a, b);
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#[rustc_doc_only_macro] |
|
||||||
macro_rules! assert { |
|
||||||
($cond:expr) => ({ /* compiler built-in */ }); |
|
||||||
($cond:expr,) => ({ /* compiler built-in */ }); |
|
||||||
($cond:expr, $($arg:tt)+) => ({ /* compiler built-in */ }); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// A macro for defining `#[cfg]` if-else statements.
|
|
||||||
///
|
|
||||||
/// This is similar to the `if/elif` C preprocessor macro by allowing definition
|
|
||||||
/// of a cascade of `#[cfg]` cases, emitting the implementation which matches
|
|
||||||
/// first.
|
|
||||||
///
|
|
||||||
/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code
|
|
||||||
/// without having to rewrite each clause multiple times.
|
|
||||||
macro_rules! cfg_if { |
|
||||||
($( |
|
||||||
if #[cfg($($meta:meta),*)] { $($it:item)* } |
|
||||||
) else * else { |
|
||||||
$($it2:item)* |
|
||||||
}) => { |
|
||||||
__cfg_if_items! { |
|
||||||
() ; |
|
||||||
$( ( ($($meta),*) ($($it)*) ), )* |
|
||||||
( () ($($it2)*) ), |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
macro_rules! __cfg_if_items { |
|
||||||
(($($not:meta,)*) ; ) => {}; |
|
||||||
(($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => { |
|
||||||
__cfg_if_apply! { cfg(all(not(any($($not),*)), $($m,)*)), $($it)* } |
|
||||||
__cfg_if_items! { ($($not,)* $($m,)*) ; $($rest)* } |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
macro_rules! __cfg_if_apply { |
|
||||||
($m:meta, $($it:item)*) => { |
|
||||||
$(#[$m] $it)* |
|
||||||
} |
|
||||||
} |
|
@ -1,143 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
//
|
|
||||||
// Original implementation taken from rust-memchr
|
|
||||||
// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
|
|
||||||
|
|
||||||
/// A safe interface to `memchr`.
|
|
||||||
///
|
|
||||||
/// Returns the index corresponding to the first occurrence of `needle` in
|
|
||||||
/// `haystack`, or `None` if one is not found.
|
|
||||||
///
|
|
||||||
/// memchr reduces to super-optimized machine code at around an order of
|
|
||||||
/// magnitude faster than `haystack.iter().position(|&b| b == needle)`.
|
|
||||||
/// (See benchmarks.)
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// This shows how to find the first position of a byte in a byte string.
|
|
||||||
///
|
|
||||||
/// ```ignore (cannot-doctest-private-modules)
|
|
||||||
/// use memchr::memchr;
|
|
||||||
///
|
|
||||||
/// let haystack = b"the quick brown fox";
|
|
||||||
/// assert_eq!(memchr(b'k', haystack), Some(8));
|
|
||||||
/// ```
|
|
||||||
#[inline] |
|
||||||
pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> { |
|
||||||
::sys::memchr::memchr(needle, haystack) |
|
||||||
} |
|
||||||
|
|
||||||
/// A safe interface to `memrchr`.
|
|
||||||
///
|
|
||||||
/// Returns the index corresponding to the last occurrence of `needle` in
|
|
||||||
/// `haystack`, or `None` if one is not found.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// This shows how to find the last position of a byte in a byte string.
|
|
||||||
///
|
|
||||||
/// ```ignore (cannot-doctest-private-modules)
|
|
||||||
/// use memchr::memrchr;
|
|
||||||
///
|
|
||||||
/// let haystack = b"the quick brown fox";
|
|
||||||
/// assert_eq!(memrchr(b'o', haystack), Some(17));
|
|
||||||
/// ```
|
|
||||||
#[inline] |
|
||||||
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> { |
|
||||||
::sys::memchr::memrchr(needle, haystack) |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(test)] |
|
||||||
mod tests { |
|
||||||
// test the implementations for the current plattform
|
|
||||||
use super::{memchr, memrchr}; |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn matches_one() { |
|
||||||
assert_eq!(Some(0), memchr(b'a', b"a")); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn matches_begin() { |
|
||||||
assert_eq!(Some(0), memchr(b'a', b"aaaa")); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn matches_end() { |
|
||||||
assert_eq!(Some(4), memchr(b'z', b"aaaaz")); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn matches_nul() { |
|
||||||
assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00")); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn matches_past_nul() { |
|
||||||
assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z")); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn no_match_empty() { |
|
||||||
assert_eq!(None, memchr(b'a', b"")); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn no_match() { |
|
||||||
assert_eq!(None, memchr(b'a', b"xyz")); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn matches_one_reversed() { |
|
||||||
assert_eq!(Some(0), memrchr(b'a', b"a")); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn matches_begin_reversed() { |
|
||||||
assert_eq!(Some(3), memrchr(b'a', b"aaaa")); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn matches_end_reversed() { |
|
||||||
assert_eq!(Some(0), memrchr(b'z', b"zaaaa")); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn matches_nul_reversed() { |
|
||||||
assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00")); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn matches_past_nul_reversed() { |
|
||||||
assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa")); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn no_match_empty_reversed() { |
|
||||||
assert_eq!(None, memrchr(b'a', b"")); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn no_match_reversed() { |
|
||||||
assert_eq!(None, memrchr(b'a', b"xyz")); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn each_alignment() { |
|
||||||
let mut data = [1u8; 64]; |
|
||||||
let needle = 2; |
|
||||||
let pos = 40; |
|
||||||
data[pos] = needle; |
|
||||||
for start in 0..16 { |
|
||||||
assert_eq!(Some(pos - start), memchr(needle, &data[start..])); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,128 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Networking primitives for TCP/UDP communication.
|
|
||||||
//!
|
|
||||||
//! This module provides networking functionality for the Transmission Control and User
|
|
||||||
//! Datagram Protocols, as well as types for IP and socket addresses.
|
|
||||||
//!
|
|
||||||
//! # Organization
|
|
||||||
//!
|
|
||||||
//! * [`TcpListener`] and [`TcpStream`] provide functionality for communication over TCP
|
|
||||||
//! * [`UdpSocket`] provides functionality for communication over UDP
|
|
||||||
//! * [`IpAddr`] represents IP addresses of either IPv4 or IPv6; [`Ipv4Addr`] and
|
|
||||||
//! [`Ipv6Addr`] are respectively IPv4 and IPv6 addresses
|
|
||||||
//! * [`SocketAddr`] represents socket addresses of either IPv4 or IPv6; [`SocketAddrV4`]
|
|
||||||
//! and [`SocketAddrV6`] are respectively IPv4 and IPv6 socket addresses
|
|
||||||
//! * [`ToSocketAddrs`] is a trait that used for generic address resolution when interacting
|
|
||||||
//! with networking objects like [`TcpListener`], [`TcpStream`] or [`UdpSocket`]
|
|
||||||
//! * Other types are return or parameter types for various methods in this module
|
|
||||||
//!
|
|
||||||
//! [`IpAddr`]: ../../std/net/enum.IpAddr.html
|
|
||||||
//! [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html
|
|
||||||
//! [`Ipv6Addr`]: ../../std/net/struct.Ipv6Addr.html
|
|
||||||
//! [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
|
|
||||||
//! [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html
|
|
||||||
//! [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html
|
|
||||||
//! [`TcpListener`]: ../../std/net/struct.TcpListener.html
|
|
||||||
//! [`TcpStream`]: ../../std/net/struct.TcpStream.html
|
|
||||||
//! [`ToSocketAddrs`]: ../../std/net/trait.ToSocketAddrs.html
|
|
||||||
//! [`UdpSocket`]: ../../std/net/struct.UdpSocket.html
|
|
||||||
|
|
||||||
#![stable(feature = "rust1", since = "1.0.0")] |
|
||||||
|
|
||||||
use io::{self, Error, ErrorKind}; |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use self::ip::{IpAddr, Ipv4Addr, Ipv6Addr, Ipv6MulticastScope}; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use self::addr::{SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs}; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use self::tcp::{TcpStream, TcpListener, Incoming}; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use self::udp::UdpSocket; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use self::parser::AddrParseError; |
|
||||||
|
|
||||||
mod ip; |
|
||||||
mod addr; |
|
||||||
mod tcp; |
|
||||||
mod udp; |
|
||||||
mod parser; |
|
||||||
#[cfg(test)] |
|
||||||
mod test; |
|
||||||
|
|
||||||
/// Possible values which can be passed to the [`shutdown`] method of
|
|
||||||
/// [`TcpStream`].
|
|
||||||
///
|
|
||||||
/// [`shutdown`]: struct.TcpStream.html#method.shutdown
|
|
||||||
/// [`TcpStream`]: struct.TcpStream.html
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)] |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub enum Shutdown { |
|
||||||
/// The reading portion of the [`TcpStream`] should be shut down.
|
|
||||||
///
|
|
||||||
/// All currently blocked and future [reads] will return [`Ok(0)`].
|
|
||||||
///
|
|
||||||
/// [`TcpStream`]: ../../std/net/struct.TcpStream.html
|
|
||||||
/// [reads]: ../../std/io/trait.Read.html
|
|
||||||
/// [`Ok(0)`]: ../../std/result/enum.Result.html#variant.Ok
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
Read, |
|
||||||
/// The writing portion of the [`TcpStream`] should be shut down.
|
|
||||||
///
|
|
||||||
/// All currently blocked and future [writes] will return an error.
|
|
||||||
///
|
|
||||||
/// [`TcpStream`]: ../../std/net/struct.TcpStream.html
|
|
||||||
/// [writes]: ../../std/io/trait.Write.html
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
Write, |
|
||||||
/// Both the reading and the writing portions of the [`TcpStream`] should be shut down.
|
|
||||||
///
|
|
||||||
/// See [`Shutdown::Read`] and [`Shutdown::Write`] for more information.
|
|
||||||
///
|
|
||||||
/// [`TcpStream`]: ../../std/net/struct.TcpStream.html
|
|
||||||
/// [`Shutdown::Read`]: #variant.Read
|
|
||||||
/// [`Shutdown::Write`]: #variant.Write
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
Both, |
|
||||||
} |
|
||||||
|
|
||||||
#[doc(hidden)] |
|
||||||
trait NetInt { |
|
||||||
fn from_be(i: Self) -> Self; |
|
||||||
fn to_be(&self) -> Self; |
|
||||||
} |
|
||||||
macro_rules! doit { |
|
||||||
($($t:ident)*) => ($(impl NetInt for $t { |
|
||||||
fn from_be(i: Self) -> Self { <$t>::from_be(i) } |
|
||||||
fn to_be(&self) -> Self { <$t>::to_be(*self) } |
|
||||||
})*) |
|
||||||
} |
|
||||||
doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize } |
|
||||||
|
|
||||||
fn hton<I: NetInt>(i: I) -> I { i.to_be() } |
|
||||||
fn ntoh<I: NetInt>(i: I) -> I { I::from_be(i) } |
|
||||||
|
|
||||||
fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T> |
|
||||||
where F: FnMut(&SocketAddr) -> io::Result<T> |
|
||||||
{ |
|
||||||
let mut last_err = None; |
|
||||||
for addr in addr.to_socket_addrs()? { |
|
||||||
match f(&addr) { |
|
||||||
Ok(l) => return Ok(l), |
|
||||||
Err(e) => last_err = Some(e), |
|
||||||
} |
|
||||||
} |
|
||||||
Err(last_err.unwrap_or_else(|| { |
|
||||||
Error::new(ErrorKind::InvalidInput, |
|
||||||
"could not resolve to any addresses") |
|
||||||
})) |
|
||||||
} |
|
@ -1,414 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! A private parser implementation of IPv4, IPv6, and socket addresses.
|
|
||||||
//!
|
|
||||||
//! This module is "publicly exported" through the `FromStr` implementations
|
|
||||||
//! below.
|
|
||||||
|
|
||||||
use error::Error; |
|
||||||
use fmt; |
|
||||||
use net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; |
|
||||||
use str::FromStr; |
|
||||||
|
|
||||||
struct Parser<'a> { |
|
||||||
// parsing as ASCII, so can use byte array
|
|
||||||
s: &'a [u8], |
|
||||||
pos: usize, |
|
||||||
} |
|
||||||
|
|
||||||
impl<'a> Parser<'a> { |
|
||||||
fn new(s: &'a str) -> Parser<'a> { |
|
||||||
Parser { |
|
||||||
s: s.as_bytes(), |
|
||||||
pos: 0, |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fn is_eof(&self) -> bool { |
|
||||||
self.pos == self.s.len() |
|
||||||
} |
|
||||||
|
|
||||||
// Commit only if parser returns Some
|
|
||||||
fn read_atomically<T, F>(&mut self, cb: F) -> Option<T> where |
|
||||||
F: FnOnce(&mut Parser) -> Option<T>, |
|
||||||
{ |
|
||||||
let pos = self.pos; |
|
||||||
let r = cb(self); |
|
||||||
if r.is_none() { |
|
||||||
self.pos = pos; |
|
||||||
} |
|
||||||
r |
|
||||||
} |
|
||||||
|
|
||||||
// Commit only if parser read till EOF
|
|
||||||
fn read_till_eof<T, F>(&mut self, cb: F) -> Option<T> where |
|
||||||
F: FnOnce(&mut Parser) -> Option<T>, |
|
||||||
{ |
|
||||||
self.read_atomically(move |p| { |
|
||||||
cb(p).filter(|_| p.is_eof()) |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
// Return result of first successful parser
|
|
||||||
fn read_or<T>(&mut self, parsers: &mut [Box<dyn FnMut(&mut Parser) -> Option<T> + 'static>]) |
|
||||||
-> Option<T> { |
|
||||||
for pf in parsers { |
|
||||||
if let Some(r) = self.read_atomically(|p: &mut Parser| pf(p)) { |
|
||||||
return Some(r); |
|
||||||
} |
|
||||||
} |
|
||||||
None |
|
||||||
} |
|
||||||
|
|
||||||
// Apply 3 parsers sequentially
|
|
||||||
fn read_seq_3<A, B, C, PA, PB, PC>(&mut self, |
|
||||||
pa: PA, |
|
||||||
pb: PB, |
|
||||||
pc: PC) |
|
||||||
-> Option<(A, B, C)> where |
|
||||||
PA: FnOnce(&mut Parser) -> Option<A>, |
|
||||||
PB: FnOnce(&mut Parser) -> Option<B>, |
|
||||||
PC: FnOnce(&mut Parser) -> Option<C>, |
|
||||||
{ |
|
||||||
self.read_atomically(move |p| { |
|
||||||
let a = pa(p); |
|
||||||
let b = if a.is_some() { pb(p) } else { None }; |
|
||||||
let c = if b.is_some() { pc(p) } else { None }; |
|
||||||
match (a, b, c) { |
|
||||||
(Some(a), Some(b), Some(c)) => Some((a, b, c)), |
|
||||||
_ => None |
|
||||||
} |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
// Read next char
|
|
||||||
fn read_char(&mut self) -> Option<char> { |
|
||||||
if self.is_eof() { |
|
||||||
None |
|
||||||
} else { |
|
||||||
let r = self.s[self.pos] as char; |
|
||||||
self.pos += 1; |
|
||||||
Some(r) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// Return char and advance iff next char is equal to requested
|
|
||||||
fn read_given_char(&mut self, c: char) -> Option<char> { |
|
||||||
self.read_atomically(|p| { |
|
||||||
match p.read_char() { |
|
||||||
Some(next) if next == c => Some(next), |
|
||||||
_ => None, |
|
||||||
} |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
// Read digit
|
|
||||||
fn read_digit(&mut self, radix: u8) -> Option<u8> { |
|
||||||
fn parse_digit(c: char, radix: u8) -> Option<u8> { |
|
||||||
let c = c as u8; |
|
||||||
// assuming radix is either 10 or 16
|
|
||||||
if c >= b'0' && c <= b'9' { |
|
||||||
Some(c - b'0') |
|
||||||
} else if radix > 10 && c >= b'a' && c < b'a' + (radix - 10) { |
|
||||||
Some(c - b'a' + 10) |
|
||||||
} else if radix > 10 && c >= b'A' && c < b'A' + (radix - 10) { |
|
||||||
Some(c - b'A' + 10) |
|
||||||
} else { |
|
||||||
None |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
self.read_atomically(|p| { |
|
||||||
p.read_char().and_then(|c| parse_digit(c, radix)) |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn read_number_impl(&mut self, radix: u8, max_digits: u32, upto: u32) -> Option<u32> { |
|
||||||
let mut r = 0; |
|
||||||
let mut digit_count = 0; |
|
||||||
loop { |
|
||||||
match self.read_digit(radix) { |
|
||||||
Some(d) => { |
|
||||||
r = r * (radix as u32) + (d as u32); |
|
||||||
digit_count += 1; |
|
||||||
if digit_count > max_digits || r >= upto { |
|
||||||
return None |
|
||||||
} |
|
||||||
} |
|
||||||
None => { |
|
||||||
if digit_count == 0 { |
|
||||||
return None |
|
||||||
} else { |
|
||||||
return Some(r) |
|
||||||
} |
|
||||||
} |
|
||||||
}; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// Read number, failing if max_digits of number value exceeded
|
|
||||||
fn read_number(&mut self, radix: u8, max_digits: u32, upto: u32) -> Option<u32> { |
|
||||||
self.read_atomically(|p| p.read_number_impl(radix, max_digits, upto)) |
|
||||||
} |
|
||||||
|
|
||||||
fn read_ipv4_addr_impl(&mut self) -> Option<Ipv4Addr> { |
|
||||||
let mut bs = [0; 4]; |
|
||||||
let mut i = 0; |
|
||||||
while i < 4 { |
|
||||||
if i != 0 && self.read_given_char('.').is_none() { |
|
||||||
return None; |
|
||||||
} |
|
||||||
|
|
||||||
bs[i] = self.read_number(10, 3, 0x100).map(|n| n as u8)?; |
|
||||||
i += 1; |
|
||||||
} |
|
||||||
Some(Ipv4Addr::new(bs[0], bs[1], bs[2], bs[3])) |
|
||||||
} |
|
||||||
|
|
||||||
// Read IPv4 address
|
|
||||||
fn read_ipv4_addr(&mut self) -> Option<Ipv4Addr> { |
|
||||||
self.read_atomically(|p| p.read_ipv4_addr_impl()) |
|
||||||
} |
|
||||||
|
|
||||||
fn read_ipv6_addr_impl(&mut self) -> Option<Ipv6Addr> { |
|
||||||
fn ipv6_addr_from_head_tail(head: &[u16], tail: &[u16]) -> Ipv6Addr { |
|
||||||
assert!(head.len() + tail.len() <= 8); |
|
||||||
let mut gs = [0; 8]; |
|
||||||
gs[..head.len()].copy_from_slice(head); |
|
||||||
gs[(8 - tail.len()) .. 8].copy_from_slice(tail); |
|
||||||
Ipv6Addr::new(gs[0], gs[1], gs[2], gs[3], gs[4], gs[5], gs[6], gs[7]) |
|
||||||
} |
|
||||||
|
|
||||||
fn read_groups(p: &mut Parser, groups: &mut [u16; 8], limit: usize) |
|
||||||
-> (usize, bool) { |
|
||||||
let mut i = 0; |
|
||||||
while i < limit { |
|
||||||
if i < limit - 1 { |
|
||||||
let ipv4 = p.read_atomically(|p| { |
|
||||||
if i == 0 || p.read_given_char(':').is_some() { |
|
||||||
p.read_ipv4_addr() |
|
||||||
} else { |
|
||||||
None |
|
||||||
} |
|
||||||
}); |
|
||||||
if let Some(v4_addr) = ipv4 { |
|
||||||
let octets = v4_addr.octets(); |
|
||||||
groups[i + 0] = ((octets[0] as u16) << 8) | (octets[1] as u16); |
|
||||||
groups[i + 1] = ((octets[2] as u16) << 8) | (octets[3] as u16); |
|
||||||
return (i + 2, true); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
let group = p.read_atomically(|p| { |
|
||||||
if i == 0 || p.read_given_char(':').is_some() { |
|
||||||
p.read_number(16, 4, 0x10000).map(|n| n as u16) |
|
||||||
} else { |
|
||||||
None |
|
||||||
} |
|
||||||
}); |
|
||||||
match group { |
|
||||||
Some(g) => groups[i] = g, |
|
||||||
None => return (i, false) |
|
||||||
} |
|
||||||
i += 1; |
|
||||||
} |
|
||||||
(i, false) |
|
||||||
} |
|
||||||
|
|
||||||
let mut head = [0; 8]; |
|
||||||
let (head_size, head_ipv4) = read_groups(self, &mut head, 8); |
|
||||||
|
|
||||||
if head_size == 8 { |
|
||||||
return Some(Ipv6Addr::new( |
|
||||||
head[0], head[1], head[2], head[3], |
|
||||||
head[4], head[5], head[6], head[7])) |
|
||||||
} |
|
||||||
|
|
||||||
// IPv4 part is not allowed before `::`
|
|
||||||
if head_ipv4 { |
|
||||||
return None |
|
||||||
} |
|
||||||
|
|
||||||
// read `::` if previous code parsed less than 8 groups
|
|
||||||
if !self.read_given_char(':').is_some() || !self.read_given_char(':').is_some() { |
|
||||||
return None; |
|
||||||
} |
|
||||||
|
|
||||||
let mut tail = [0; 8]; |
|
||||||
// `::` indicates one or more groups of 16 bits of zeros
|
|
||||||
let limit = 8 - (head_size + 1); |
|
||||||
let (tail_size, _) = read_groups(self, &mut tail, limit); |
|
||||||
Some(ipv6_addr_from_head_tail(&head[..head_size], &tail[..tail_size])) |
|
||||||
} |
|
||||||
|
|
||||||
fn read_ipv6_addr(&mut self) -> Option<Ipv6Addr> { |
|
||||||
self.read_atomically(|p| p.read_ipv6_addr_impl()) |
|
||||||
} |
|
||||||
|
|
||||||
fn read_ip_addr(&mut self) -> Option<IpAddr> { |
|
||||||
let ipv4_addr = |p: &mut Parser| p.read_ipv4_addr().map(IpAddr::V4); |
|
||||||
let ipv6_addr = |p: &mut Parser| p.read_ipv6_addr().map(IpAddr::V6); |
|
||||||
self.read_or(&mut [Box::new(ipv4_addr), Box::new(ipv6_addr)]) |
|
||||||
} |
|
||||||
|
|
||||||
fn read_socket_addr_v4(&mut self) -> Option<SocketAddrV4> { |
|
||||||
let ip_addr = |p: &mut Parser| p.read_ipv4_addr(); |
|
||||||
let colon = |p: &mut Parser| p.read_given_char(':'); |
|
||||||
let port = |p: &mut Parser| { |
|
||||||
p.read_number(10, 5, 0x10000).map(|n| n as u16) |
|
||||||
}; |
|
||||||
|
|
||||||
self.read_seq_3(ip_addr, colon, port).map(|t| { |
|
||||||
let (ip, _, port): (Ipv4Addr, char, u16) = t; |
|
||||||
SocketAddrV4::new(ip, port) |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn read_socket_addr_v6(&mut self) -> Option<SocketAddrV6> { |
|
||||||
let ip_addr = |p: &mut Parser| { |
|
||||||
let open_br = |p: &mut Parser| p.read_given_char('['); |
|
||||||
let ip_addr = |p: &mut Parser| p.read_ipv6_addr(); |
|
||||||
let clos_br = |p: &mut Parser| p.read_given_char(']'); |
|
||||||
p.read_seq_3(open_br, ip_addr, clos_br).map(|t| t.1) |
|
||||||
}; |
|
||||||
let colon = |p: &mut Parser| p.read_given_char(':'); |
|
||||||
let port = |p: &mut Parser| { |
|
||||||
p.read_number(10, 5, 0x10000).map(|n| n as u16) |
|
||||||
}; |
|
||||||
|
|
||||||
self.read_seq_3(ip_addr, colon, port).map(|t| { |
|
||||||
let (ip, _, port): (Ipv6Addr, char, u16) = t; |
|
||||||
SocketAddrV6::new(ip, port, 0, 0) |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
fn read_socket_addr(&mut self) -> Option<SocketAddr> { |
|
||||||
let v4 = |p: &mut Parser| p.read_socket_addr_v4().map(SocketAddr::V4); |
|
||||||
let v6 = |p: &mut Parser| p.read_socket_addr_v6().map(SocketAddr::V6); |
|
||||||
self.read_or(&mut [Box::new(v4), Box::new(v6)]) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "ip_addr", since = "1.7.0")] |
|
||||||
impl FromStr for IpAddr { |
|
||||||
type Err = AddrParseError; |
|
||||||
fn from_str(s: &str) -> Result<IpAddr, AddrParseError> { |
|
||||||
match Parser::new(s).read_till_eof(|p| p.read_ip_addr()) { |
|
||||||
Some(s) => Ok(s), |
|
||||||
None => Err(AddrParseError(())) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl FromStr for Ipv4Addr { |
|
||||||
type Err = AddrParseError; |
|
||||||
fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> { |
|
||||||
match Parser::new(s).read_till_eof(|p| p.read_ipv4_addr()) { |
|
||||||
Some(s) => Ok(s), |
|
||||||
None => Err(AddrParseError(())) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl FromStr for Ipv6Addr { |
|
||||||
type Err = AddrParseError; |
|
||||||
fn from_str(s: &str) -> Result<Ipv6Addr, AddrParseError> { |
|
||||||
match Parser::new(s).read_till_eof(|p| p.read_ipv6_addr()) { |
|
||||||
Some(s) => Ok(s), |
|
||||||
None => Err(AddrParseError(())) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "socket_addr_from_str", since = "1.5.0")] |
|
||||||
impl FromStr for SocketAddrV4 { |
|
||||||
type Err = AddrParseError; |
|
||||||
fn from_str(s: &str) -> Result<SocketAddrV4, AddrParseError> { |
|
||||||
match Parser::new(s).read_till_eof(|p| p.read_socket_addr_v4()) { |
|
||||||
Some(s) => Ok(s), |
|
||||||
None => Err(AddrParseError(())), |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "socket_addr_from_str", since = "1.5.0")] |
|
||||||
impl FromStr for SocketAddrV6 { |
|
||||||
type Err = AddrParseError; |
|
||||||
fn from_str(s: &str) -> Result<SocketAddrV6, AddrParseError> { |
|
||||||
match Parser::new(s).read_till_eof(|p| p.read_socket_addr_v6()) { |
|
||||||
Some(s) => Ok(s), |
|
||||||
None => Err(AddrParseError(())), |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
impl FromStr for SocketAddr { |
|
||||||
type Err = AddrParseError; |
|
||||||
fn from_str(s: &str) -> Result<SocketAddr, AddrParseError> { |
|
||||||
match Parser::new(s).read_till_eof(|p| p.read_socket_addr()) { |
|
||||||
Some(s) => Ok(s), |
|
||||||
None => Err(AddrParseError(())), |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/// An error which can be returned when parsing an IP address or a socket address.
|
|
||||||
///
|
|
||||||
/// This error is used as the error type for the [`FromStr`] implementation for
|
|
||||||
/// [`IpAddr`], [`Ipv4Addr`], [`Ipv6Addr`], [`SocketAddr`], [`SocketAddrV4`], and
|
|
||||||
/// [`SocketAddrV6`].
|
|
||||||
///
|
|
||||||
/// # Potential causes
|
|
||||||
///
|
|
||||||
/// `AddrParseError` may be thrown because the provided string does not parse as the given type,
|
|
||||||
/// often because it includes information only handled by a different address type.
|
|
||||||
///
|
|
||||||
/// ```should_panic
|
|
||||||
/// use std::net::IpAddr;
|
|
||||||
/// let _foo: IpAddr = "127.0.0.1:8080".parse().expect("Cannot handle the socket port");
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// [`IpAddr`] doesn't handle the port. Use [`SocketAddr`] instead.
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::net::SocketAddr;
|
|
||||||
///
|
|
||||||
/// // No problem, the `panic!` message has disappeared.
|
|
||||||
/// let _foo: SocketAddr = "127.0.0.1:8080".parse().expect("unreachable panic");
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// [`FromStr`]: ../../std/str/trait.FromStr.html
|
|
||||||
/// [`IpAddr`]: ../../std/net/enum.IpAddr.html
|
|
||||||
/// [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html
|
|
||||||
/// [`Ipv6Addr`]: ../../std/net/struct.Ipv6Addr.html
|
|
||||||
/// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
|
|
||||||
/// [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html
|
|
||||||
/// [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)] |
|
||||||
pub struct AddrParseError(()); |
|
||||||
|
|
||||||
#[stable(feature = "addr_parse_error_error", since = "1.4.0")] |
|
||||||
impl fmt::Display for AddrParseError { |
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
|
||||||
fmt.write_str(self.description()) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "addr_parse_error_error", since = "1.4.0")] |
|
||||||
impl Error for AddrParseError { |
|
||||||
fn description(&self) -> &str { |
|
||||||
"invalid IP address syntax" |
|
||||||
} |
|
||||||
} |
|
@ -1,57 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#![allow(warnings)] // not used on emscripten
|
|
||||||
|
|
||||||
use env; |
|
||||||
use net::{SocketAddr, SocketAddrV4, SocketAddrV6, Ipv4Addr, Ipv6Addr, ToSocketAddrs}; |
|
||||||
use sync::atomic::{AtomicUsize, Ordering}; |
|
||||||
|
|
||||||
static PORT: AtomicUsize = AtomicUsize::new(0); |
|
||||||
|
|
||||||
pub fn next_test_ip4() -> SocketAddr { |
|
||||||
let port = PORT.fetch_add(1, Ordering::SeqCst) as u16 + base_port(); |
|
||||||
SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), port)) |
|
||||||
} |
|
||||||
|
|
||||||
pub fn next_test_ip6() -> SocketAddr { |
|
||||||
let port = PORT.fetch_add(1, Ordering::SeqCst) as u16 + base_port(); |
|
||||||
SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), |
|
||||||
port, 0, 0)) |
|
||||||
} |
|
||||||
|
|
||||||
pub fn sa4(a: Ipv4Addr, p: u16) -> SocketAddr { |
|
||||||
SocketAddr::V4(SocketAddrV4::new(a, p)) |
|
||||||
} |
|
||||||
|
|
||||||
pub fn sa6(a: Ipv6Addr, p: u16) -> SocketAddr { |
|
||||||
SocketAddr::V6(SocketAddrV6::new(a, p, 0, 0)) |
|
||||||
} |
|
||||||
|
|
||||||
pub fn tsa<A: ToSocketAddrs>(a: A) -> Result<Vec<SocketAddr>, String> { |
|
||||||
match a.to_socket_addrs() { |
|
||||||
Ok(a) => Ok(a.collect()), |
|
||||||
Err(e) => Err(e.to_string()), |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// The bots run multiple builds at the same time, and these builds
|
|
||||||
// all want to use ports. This function figures out which workspace
|
|
||||||
// it is running in and assigns a port range based on it.
|
|
||||||
fn base_port() -> u16 { |
|
||||||
let cwd = env::current_dir().unwrap(); |
|
||||||
let dirs = ["32-opt", "32-nopt", |
|
||||||
"musl-64-opt", "cross-opt", |
|
||||||
"64-opt", "64-nopt", "64-opt-vg", "64-debug-opt", |
|
||||||
"all-opt", "snap3", "dist"]; |
|
||||||
dirs.iter().enumerate().find(|&(_, dir)| { |
|
||||||
cwd.to_str().unwrap().contains(dir) |
|
||||||
}).map(|p| p.0).unwrap_or(0) as u16 * 1000 + 19600 |
|
||||||
} |
|
@ -1,296 +0,0 @@ |
|||||||
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Additional functionality for numerics.
|
|
||||||
//!
|
|
||||||
//! This module provides some extra types that are useful when doing numerical
|
|
||||||
//! work. See the individual documentation for each piece for more information.
|
|
||||||
|
|
||||||
#![stable(feature = "rust1", since = "1.0.0")] |
|
||||||
#![allow(missing_docs)] |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::num::{FpCategory, ParseIntError, ParseFloatError, TryFromIntError}; |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use core::num::Wrapping; |
|
||||||
|
|
||||||
#[stable(feature = "nonzero", since = "1.28.0")] |
|
||||||
pub use core::num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize}; |
|
||||||
|
|
||||||
#[cfg(test)] use fmt; |
|
||||||
#[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem}; |
|
||||||
|
|
||||||
/// Helper function for testing numeric operations
|
|
||||||
#[cfg(test)] |
|
||||||
pub fn test_num<T>(ten: T, two: T) where |
|
||||||
T: PartialEq |
|
||||||
+ Add<Output=T> + Sub<Output=T> |
|
||||||
+ Mul<Output=T> + Div<Output=T> |
|
||||||
+ Rem<Output=T> + fmt::Debug |
|
||||||
+ Copy |
|
||||||
{ |
|
||||||
assert_eq!(ten.add(two), ten + two); |
|
||||||
assert_eq!(ten.sub(two), ten - two); |
|
||||||
assert_eq!(ten.mul(two), ten * two); |
|
||||||
assert_eq!(ten.div(two), ten / two); |
|
||||||
assert_eq!(ten.rem(two), ten % two); |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(test)] |
|
||||||
mod tests { |
|
||||||
use u8; |
|
||||||
use u16; |
|
||||||
use u32; |
|
||||||
use u64; |
|
||||||
use usize; |
|
||||||
use ops::Mul; |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_saturating_add_uint() { |
|
||||||
use usize::MAX; |
|
||||||
assert_eq!(3_usize.saturating_add(5_usize), 8_usize); |
|
||||||
assert_eq!(3_usize.saturating_add(MAX-1), MAX); |
|
||||||
assert_eq!(MAX.saturating_add(MAX), MAX); |
|
||||||
assert_eq!((MAX-2).saturating_add(1), MAX-1); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_saturating_sub_uint() { |
|
||||||
use usize::MAX; |
|
||||||
assert_eq!(5_usize.saturating_sub(3_usize), 2_usize); |
|
||||||
assert_eq!(3_usize.saturating_sub(5_usize), 0_usize); |
|
||||||
assert_eq!(0_usize.saturating_sub(1_usize), 0_usize); |
|
||||||
assert_eq!((MAX-1).saturating_sub(MAX), 0); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_saturating_add_int() { |
|
||||||
use isize::{MIN,MAX}; |
|
||||||
assert_eq!(3i32.saturating_add(5), 8); |
|
||||||
assert_eq!(3isize.saturating_add(MAX-1), MAX); |
|
||||||
assert_eq!(MAX.saturating_add(MAX), MAX); |
|
||||||
assert_eq!((MAX-2).saturating_add(1), MAX-1); |
|
||||||
assert_eq!(3i32.saturating_add(-5), -2); |
|
||||||
assert_eq!(MIN.saturating_add(-1), MIN); |
|
||||||
assert_eq!((-2isize).saturating_add(-MAX), MIN); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_saturating_sub_int() { |
|
||||||
use isize::{MIN,MAX}; |
|
||||||
assert_eq!(3i32.saturating_sub(5), -2); |
|
||||||
assert_eq!(MIN.saturating_sub(1), MIN); |
|
||||||
assert_eq!((-2isize).saturating_sub(MAX), MIN); |
|
||||||
assert_eq!(3i32.saturating_sub(-5), 8); |
|
||||||
assert_eq!(3isize.saturating_sub(-(MAX-1)), MAX); |
|
||||||
assert_eq!(MAX.saturating_sub(-MAX), MAX); |
|
||||||
assert_eq!((MAX-2).saturating_sub(-1), MAX-1); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_checked_add() { |
|
||||||
let five_less = usize::MAX - 5; |
|
||||||
assert_eq!(five_less.checked_add(0), Some(usize::MAX - 5)); |
|
||||||
assert_eq!(five_less.checked_add(1), Some(usize::MAX - 4)); |
|
||||||
assert_eq!(five_less.checked_add(2), Some(usize::MAX - 3)); |
|
||||||
assert_eq!(five_less.checked_add(3), Some(usize::MAX - 2)); |
|
||||||
assert_eq!(five_less.checked_add(4), Some(usize::MAX - 1)); |
|
||||||
assert_eq!(five_less.checked_add(5), Some(usize::MAX)); |
|
||||||
assert_eq!(five_less.checked_add(6), None); |
|
||||||
assert_eq!(five_less.checked_add(7), None); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_checked_sub() { |
|
||||||
assert_eq!(5_usize.checked_sub(0), Some(5)); |
|
||||||
assert_eq!(5_usize.checked_sub(1), Some(4)); |
|
||||||
assert_eq!(5_usize.checked_sub(2), Some(3)); |
|
||||||
assert_eq!(5_usize.checked_sub(3), Some(2)); |
|
||||||
assert_eq!(5_usize.checked_sub(4), Some(1)); |
|
||||||
assert_eq!(5_usize.checked_sub(5), Some(0)); |
|
||||||
assert_eq!(5_usize.checked_sub(6), None); |
|
||||||
assert_eq!(5_usize.checked_sub(7), None); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_checked_mul() { |
|
||||||
let third = usize::MAX / 3; |
|
||||||
assert_eq!(third.checked_mul(0), Some(0)); |
|
||||||
assert_eq!(third.checked_mul(1), Some(third)); |
|
||||||
assert_eq!(third.checked_mul(2), Some(third * 2)); |
|
||||||
assert_eq!(third.checked_mul(3), Some(third * 3)); |
|
||||||
assert_eq!(third.checked_mul(4), None); |
|
||||||
} |
|
||||||
|
|
||||||
macro_rules! test_is_power_of_two { |
|
||||||
($test_name:ident, $T:ident) => ( |
|
||||||
fn $test_name() { |
|
||||||
#![test] |
|
||||||
assert_eq!((0 as $T).is_power_of_two(), false); |
|
||||||
assert_eq!((1 as $T).is_power_of_two(), true); |
|
||||||
assert_eq!((2 as $T).is_power_of_two(), true); |
|
||||||
assert_eq!((3 as $T).is_power_of_two(), false); |
|
||||||
assert_eq!((4 as $T).is_power_of_two(), true); |
|
||||||
assert_eq!((5 as $T).is_power_of_two(), false); |
|
||||||
assert_eq!(($T::MAX / 2 + 1).is_power_of_two(), true); |
|
||||||
} |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
test_is_power_of_two!{ test_is_power_of_two_u8, u8 } |
|
||||||
test_is_power_of_two!{ test_is_power_of_two_u16, u16 } |
|
||||||
test_is_power_of_two!{ test_is_power_of_two_u32, u32 } |
|
||||||
test_is_power_of_two!{ test_is_power_of_two_u64, u64 } |
|
||||||
test_is_power_of_two!{ test_is_power_of_two_uint, usize } |
|
||||||
|
|
||||||
macro_rules! test_next_power_of_two { |
|
||||||
($test_name:ident, $T:ident) => ( |
|
||||||
fn $test_name() { |
|
||||||
#![test] |
|
||||||
assert_eq!((0 as $T).next_power_of_two(), 1); |
|
||||||
let mut next_power = 1; |
|
||||||
for i in 1 as $T..40 { |
|
||||||
assert_eq!(i.next_power_of_two(), next_power); |
|
||||||
if i == next_power { next_power *= 2 } |
|
||||||
} |
|
||||||
} |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
test_next_power_of_two! { test_next_power_of_two_u8, u8 } |
|
||||||
test_next_power_of_two! { test_next_power_of_two_u16, u16 } |
|
||||||
test_next_power_of_two! { test_next_power_of_two_u32, u32 } |
|
||||||
test_next_power_of_two! { test_next_power_of_two_u64, u64 } |
|
||||||
test_next_power_of_two! { test_next_power_of_two_uint, usize } |
|
||||||
|
|
||||||
macro_rules! test_checked_next_power_of_two { |
|
||||||
($test_name:ident, $T:ident) => ( |
|
||||||
fn $test_name() { |
|
||||||
#![test] |
|
||||||
assert_eq!((0 as $T).checked_next_power_of_two(), Some(1)); |
|
||||||
let smax = $T::MAX >> 1; |
|
||||||
assert_eq!(smax.checked_next_power_of_two(), Some(smax+1)); |
|
||||||
assert_eq!((smax + 1).checked_next_power_of_two(), Some(smax + 1)); |
|
||||||
assert_eq!((smax + 2).checked_next_power_of_two(), None); |
|
||||||
assert_eq!(($T::MAX - 1).checked_next_power_of_two(), None); |
|
||||||
assert_eq!($T::MAX.checked_next_power_of_two(), None); |
|
||||||
let mut next_power = 1; |
|
||||||
for i in 1 as $T..40 { |
|
||||||
assert_eq!(i.checked_next_power_of_two(), Some(next_power)); |
|
||||||
if i == next_power { next_power *= 2 } |
|
||||||
} |
|
||||||
} |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
test_checked_next_power_of_two! { test_checked_next_power_of_two_u8, u8 } |
|
||||||
test_checked_next_power_of_two! { test_checked_next_power_of_two_u16, u16 } |
|
||||||
test_checked_next_power_of_two! { test_checked_next_power_of_two_u32, u32 } |
|
||||||
test_checked_next_power_of_two! { test_checked_next_power_of_two_u64, u64 } |
|
||||||
test_checked_next_power_of_two! { test_checked_next_power_of_two_uint, usize } |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_pow() { |
|
||||||
fn naive_pow<T: Mul<Output=T> + Copy>(one: T, base: T, exp: usize) -> T { |
|
||||||
(0..exp).fold(one, |acc, _| acc * base) |
|
||||||
} |
|
||||||
macro_rules! assert_pow { |
|
||||||
(($num:expr, $exp:expr) => $expected:expr) => {{ |
|
||||||
let result = $num.pow($exp); |
|
||||||
assert_eq!(result, $expected); |
|
||||||
assert_eq!(result, naive_pow(1, $num, $exp)); |
|
||||||
}} |
|
||||||
} |
|
||||||
assert_pow!((3u32, 0 ) => 1); |
|
||||||
assert_pow!((5u32, 1 ) => 5); |
|
||||||
assert_pow!((-4i32, 2 ) => 16); |
|
||||||
assert_pow!((8u32, 3 ) => 512); |
|
||||||
assert_pow!((2u64, 50) => 1125899906842624); |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_uint_to_str_overflow() { |
|
||||||
let mut u8_val: u8 = 255; |
|
||||||
assert_eq!(u8_val.to_string(), "255"); |
|
||||||
|
|
||||||
u8_val = u8_val.wrapping_add(1); |
|
||||||
assert_eq!(u8_val.to_string(), "0"); |
|
||||||
|
|
||||||
let mut u16_val: u16 = 65_535; |
|
||||||
assert_eq!(u16_val.to_string(), "65535"); |
|
||||||
|
|
||||||
u16_val = u16_val.wrapping_add(1); |
|
||||||
assert_eq!(u16_val.to_string(), "0"); |
|
||||||
|
|
||||||
let mut u32_val: u32 = 4_294_967_295; |
|
||||||
assert_eq!(u32_val.to_string(), "4294967295"); |
|
||||||
|
|
||||||
u32_val = u32_val.wrapping_add(1); |
|
||||||
assert_eq!(u32_val.to_string(), "0"); |
|
||||||
|
|
||||||
let mut u64_val: u64 = 18_446_744_073_709_551_615; |
|
||||||
assert_eq!(u64_val.to_string(), "18446744073709551615"); |
|
||||||
|
|
||||||
u64_val = u64_val.wrapping_add(1); |
|
||||||
assert_eq!(u64_val.to_string(), "0"); |
|
||||||
} |
|
||||||
|
|
||||||
fn from_str<T: ::str::FromStr>(t: &str) -> Option<T> { |
|
||||||
::str::FromStr::from_str(t).ok() |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn test_uint_from_str_overflow() { |
|
||||||
let mut u8_val: u8 = 255; |
|
||||||
assert_eq!(from_str::<u8>("255"), Some(u8_val)); |
|
||||||
assert_eq!(from_str::<u8>("256"), None); |
|
||||||
|
|
||||||
u8_val = u8_val.wrapping_add(1); |
|
||||||
assert_eq!(from_str::<u8>("0"), Some(u8_val)); |
|
||||||
assert_eq!(from_str::<u8>("-1"), None); |
|
||||||
|
|
||||||
let mut u16_val: u16 = 65_535; |
|
||||||
assert_eq!(from_str::<u16>("65535"), Some(u16_val)); |
|
||||||
assert_eq!(from_str::<u16>("65536"), None); |
|
||||||
|
|
||||||
u16_val = u16_val.wrapping_add(1); |
|
||||||
assert_eq!(from_str::<u16>("0"), Some(u16_val)); |
|
||||||
assert_eq!(from_str::<u16>("-1"), None); |
|
||||||
|
|
||||||
let mut u32_val: u32 = 4_294_967_295; |
|
||||||
assert_eq!(from_str::<u32>("4294967295"), Some(u32_val)); |
|
||||||
assert_eq!(from_str::<u32>("4294967296"), None); |
|
||||||
|
|
||||||
u32_val = u32_val.wrapping_add(1); |
|
||||||
assert_eq!(from_str::<u32>("0"), Some(u32_val)); |
|
||||||
assert_eq!(from_str::<u32>("-1"), None); |
|
||||||
|
|
||||||
let mut u64_val: u64 = 18_446_744_073_709_551_615; |
|
||||||
assert_eq!(from_str::<u64>("18446744073709551615"), Some(u64_val)); |
|
||||||
assert_eq!(from_str::<u64>("18446744073709551616"), None); |
|
||||||
|
|
||||||
u64_val = u64_val.wrapping_add(1); |
|
||||||
assert_eq!(from_str::<u64>("0"), Some(u64_val)); |
|
||||||
assert_eq!(from_str::<u64>("-1"), None); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)] |
|
||||||
mod bench { |
|
||||||
extern crate test; |
|
||||||
use self::test::Bencher; |
|
||||||
|
|
||||||
#[bench] |
|
||||||
fn bench_pow_function(b: &mut Bencher) { |
|
||||||
let v = (0..1024).collect::<Vec<u32>>(); |
|
||||||
b.iter(|| {v.iter().fold(0u32, |old, new| old.pow(*new as u32));}); |
|
||||||
} |
|
||||||
} |
|
@ -1,131 +0,0 @@ |
|||||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#![stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
use libc; |
|
||||||
|
|
||||||
use fs::Metadata; |
|
||||||
use sys_common::AsInner; |
|
||||||
|
|
||||||
#[allow(deprecated)] |
|
||||||
use os::android::raw; |
|
||||||
|
|
||||||
/// OS-specific extensions to [`fs::Metadata`].
|
|
||||||
///
|
|
||||||
/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
pub trait MetadataExt { |
|
||||||
/// Gain a reference to the underlying `stat` structure which contains
|
|
||||||
/// the raw information returned by the OS.
|
|
||||||
///
|
|
||||||
/// The contents of the returned `stat` are **not** consistent across
|
|
||||||
/// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
|
|
||||||
/// cross-Unix abstractions contained within the raw stat.
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
#[rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "deprecated in favor of the accessor \ |
|
||||||
methods of this trait")] |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat; |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_dev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ino(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mode(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_nlink(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_uid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_gid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_rdev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_size(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blksize(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blocks(&self) -> u64; |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
impl MetadataExt for Metadata { |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat { |
|
||||||
unsafe { |
|
||||||
&*(self.as_inner().as_inner() as *const libc::stat |
|
||||||
as *const raw::stat) |
|
||||||
} |
|
||||||
} |
|
||||||
fn st_dev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_dev as u64 |
|
||||||
} |
|
||||||
fn st_ino(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_ino as u64 |
|
||||||
} |
|
||||||
fn st_mode(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_mode as u32 |
|
||||||
} |
|
||||||
fn st_nlink(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_nlink as u64 |
|
||||||
} |
|
||||||
fn st_uid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_uid as u32 |
|
||||||
} |
|
||||||
fn st_gid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_gid as u32 |
|
||||||
} |
|
||||||
fn st_rdev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_rdev as u64 |
|
||||||
} |
|
||||||
fn st_size(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_size as u64 |
|
||||||
} |
|
||||||
fn st_atime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime as i64 |
|
||||||
} |
|
||||||
fn st_atime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_mtime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime as i64 |
|
||||||
} |
|
||||||
fn st_mtime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_ctime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime as i64 |
|
||||||
} |
|
||||||
fn st_ctime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_blksize(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blksize as u64 |
|
||||||
} |
|
||||||
fn st_blocks(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blocks as u64 |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
@ -1,16 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Android-specific definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
pub mod raw; |
|
||||||
pub mod fs; |
|
@ -1,230 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Android-specific raw type definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
#![rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "these type aliases are no longer supported by \ |
|
||||||
the standard library, the `libc` crate on \ |
|
||||||
crates.io should be used instead for the correct \ |
|
||||||
definitions")] |
|
||||||
#![allow(deprecated)] |
|
||||||
|
|
||||||
use os::raw::c_long; |
|
||||||
|
|
||||||
#[stable(feature = "pthread_t", since = "1.8.0")] |
|
||||||
pub type pthread_t = c_long; |
|
||||||
|
|
||||||
#[doc(inline)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub use self::arch::{dev_t, mode_t, blkcnt_t, blksize_t, ino_t, nlink_t, off_t, stat, time_t}; |
|
||||||
|
|
||||||
#[cfg(any(target_arch = "arm", target_arch = "x86"))] |
|
||||||
mod arch { |
|
||||||
use os::raw::{c_uint, c_uchar, c_ulonglong, c_longlong, c_ulong}; |
|
||||||
use os::unix::raw::{uid_t, gid_t}; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type dev_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type mode_t = u32; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type blksize_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type nlink_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type time_t = i64; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: c_ulonglong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __pad0: [c_uchar; 4], |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __st_ino: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: c_uint, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: c_uint, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: uid_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: gid_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: c_ulonglong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __pad3: [c_uchar; 4], |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: c_longlong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: c_ulonglong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: c_ulong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_ulong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: c_ulong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_ulong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: c_ulong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_ulong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: c_ulonglong, |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")] |
|
||||||
mod arch { |
|
||||||
use os::raw::{c_uchar, c_ulong}; |
|
||||||
use os::unix::raw::{uid_t, gid_t}; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type dev_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type mode_t = u32; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type blksize_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type nlink_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type time_t = i64; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: dev_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __pad0: [c_uchar; 4], |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __st_ino: ino_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: mode_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: nlink_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: uid_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: gid_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: dev_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __pad3: [c_uchar; 4], |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: off_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: blksize_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: blkcnt_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: time_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_ulong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: time_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_ulong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: time_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_ulong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: ino_t, |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")] |
|
||||||
mod arch { |
|
||||||
use os::raw::{c_uint, c_long, c_ulong}; |
|
||||||
use os::unix::raw::{uid_t, gid_t}; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type dev_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type mode_t = u32; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type blksize_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type nlink_t = u32; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub type time_t = i64; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: dev_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: ino_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: c_ulong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: c_uint, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: uid_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: gid_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: dev_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: c_ulong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_ulong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: c_ulong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_ulong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: c_ulong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_ulong, |
|
||||||
__unused: [c_long; 3], |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
@ -1,151 +0,0 @@ |
|||||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#![stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
use libc; |
|
||||||
|
|
||||||
use fs::Metadata; |
|
||||||
use sys_common::AsInner; |
|
||||||
|
|
||||||
#[allow(deprecated)] |
|
||||||
use os::bitrig::raw; |
|
||||||
|
|
||||||
/// OS-specific extensions to [`fs::Metadata`].
|
|
||||||
///
|
|
||||||
/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
pub trait MetadataExt { |
|
||||||
/// Gain a reference to the underlying `stat` structure which contains
|
|
||||||
/// the raw information returned by the OS.
|
|
||||||
///
|
|
||||||
/// The contents of the returned `stat` are **not** consistent across
|
|
||||||
/// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
|
|
||||||
/// cross-Unix abstractions contained within the raw stat.
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
#[rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "deprecated in favor of the accessor \ |
|
||||||
methods of this trait")] |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat; |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_dev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ino(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mode(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_nlink(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_uid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_gid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_rdev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_size(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_birthtime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_birthtime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blksize(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blocks(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_flags(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_gen(&self) -> u32; |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
impl MetadataExt for Metadata { |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat { |
|
||||||
unsafe { |
|
||||||
&*(self.as_inner().as_inner() as *const libc::stat |
|
||||||
as *const raw::stat) |
|
||||||
} |
|
||||||
} |
|
||||||
fn st_dev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_dev as u64 |
|
||||||
} |
|
||||||
fn st_ino(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_ino as u64 |
|
||||||
} |
|
||||||
fn st_mode(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_mode as u32 |
|
||||||
} |
|
||||||
fn st_nlink(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_nlink as u64 |
|
||||||
} |
|
||||||
fn st_uid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_uid as u32 |
|
||||||
} |
|
||||||
fn st_gid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_gid as u32 |
|
||||||
} |
|
||||||
fn st_rdev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_rdev as u64 |
|
||||||
} |
|
||||||
fn st_size(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_size as u64 |
|
||||||
} |
|
||||||
fn st_atime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime as i64 |
|
||||||
} |
|
||||||
fn st_atime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_mtime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime as i64 |
|
||||||
} |
|
||||||
fn st_mtime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_ctime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime as i64 |
|
||||||
} |
|
||||||
fn st_ctime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_birthtime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_birthtime as i64 |
|
||||||
} |
|
||||||
fn st_birthtime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_birthtime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_blksize(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blksize as u64 |
|
||||||
} |
|
||||||
fn st_blocks(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blocks as u64 |
|
||||||
} |
|
||||||
fn st_gen(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_gen as u32 |
|
||||||
} |
|
||||||
fn st_flags(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_flags as u32 |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
@ -1,16 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Bitrig-specific definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
pub mod raw; |
|
||||||
pub mod fs; |
|
@ -1,81 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Bitrig-specific raw type definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
#![rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "these type aliases are no longer supported by \ |
|
||||||
the standard library, the `libc` crate on \ |
|
||||||
crates.io should be used instead for the correct \ |
|
||||||
definitions")] |
|
||||||
#![allow(deprecated)] |
|
||||||
|
|
||||||
use os::raw::c_long; |
|
||||||
use os::unix::raw::{uid_t, gid_t}; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type fflags_t = u32; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; |
|
||||||
|
|
||||||
#[stable(feature = "pthread_t", since = "1.8.0")] |
|
||||||
pub type pthread_t = usize; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_flags: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gen: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_birthtime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_birthtime_nsec: i64, |
|
||||||
} |
|
@ -1,146 +0,0 @@ |
|||||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#![stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
use libc; |
|
||||||
|
|
||||||
use fs::Metadata; |
|
||||||
use sys_common::AsInner; |
|
||||||
|
|
||||||
#[allow(deprecated)] |
|
||||||
use os::dragonfly::raw; |
|
||||||
|
|
||||||
/// OS-specific extensions to [`fs::Metadata`].
|
|
||||||
///
|
|
||||||
/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
pub trait MetadataExt { |
|
||||||
/// Gain a reference to the underlying `stat` structure which contains
|
|
||||||
/// the raw information returned by the OS.
|
|
||||||
///
|
|
||||||
/// The contents of the returned `stat` are **not** consistent across
|
|
||||||
/// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
|
|
||||||
/// cross-Unix abstractions contained within the raw stat.
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
#[rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "deprecated in favor of the accessor \ |
|
||||||
methods of this trait")] |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat; |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_dev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ino(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mode(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_nlink(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_uid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_gid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_rdev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_size(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blksize(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blocks(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_flags(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_gen(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_lspare(&self) -> u32; |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
impl MetadataExt for Metadata { |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat { |
|
||||||
unsafe { |
|
||||||
&*(self.as_inner().as_inner() as *const libc::stat |
|
||||||
as *const raw::stat) |
|
||||||
} |
|
||||||
} |
|
||||||
fn st_dev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_dev as u64 |
|
||||||
} |
|
||||||
fn st_ino(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_ino as u64 |
|
||||||
} |
|
||||||
fn st_mode(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_mode as u32 |
|
||||||
} |
|
||||||
fn st_nlink(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_nlink as u64 |
|
||||||
} |
|
||||||
fn st_uid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_uid as u32 |
|
||||||
} |
|
||||||
fn st_gid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_gid as u32 |
|
||||||
} |
|
||||||
fn st_rdev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_rdev as u64 |
|
||||||
} |
|
||||||
fn st_size(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_size as u64 |
|
||||||
} |
|
||||||
fn st_atime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime as i64 |
|
||||||
} |
|
||||||
fn st_atime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_mtime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime as i64 |
|
||||||
} |
|
||||||
fn st_mtime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_ctime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime as i64 |
|
||||||
} |
|
||||||
fn st_ctime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_blksize(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blksize as u64 |
|
||||||
} |
|
||||||
fn st_blocks(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blocks as u64 |
|
||||||
} |
|
||||||
fn st_gen(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_gen as u32 |
|
||||||
} |
|
||||||
fn st_flags(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_flags as u32 |
|
||||||
} |
|
||||||
fn st_lspare(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_lspare as u32 |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
@ -1,16 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Dragonfly-specific definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
pub mod raw; |
|
||||||
pub mod fs; |
|
@ -1,82 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Dragonfly-specific raw type definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
#![rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "these type aliases are no longer supported by \ |
|
||||||
the standard library, the `libc` crate on \ |
|
||||||
crates.io should be used instead for the correct \ |
|
||||||
definitions")] |
|
||||||
#![allow(deprecated)] |
|
||||||
|
|
||||||
use os::raw::c_long; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type fflags_t = u32; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; |
|
||||||
|
|
||||||
#[stable(feature = "pthread_t", since = "1.8.0")] |
|
||||||
pub type pthread_t = usize; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: u16, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: u16, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_flags: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gen: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_lspare: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_birthtime: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_birthtime_nsec: c_long, |
|
||||||
} |
|
@ -1,130 +0,0 @@ |
|||||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#![stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
use libc; |
|
||||||
|
|
||||||
use fs::Metadata; |
|
||||||
use sys_common::AsInner; |
|
||||||
|
|
||||||
#[allow(deprecated)] |
|
||||||
use os::emscripten::raw; |
|
||||||
|
|
||||||
/// OS-specific extensions to [`fs::Metadata`].
|
|
||||||
///
|
|
||||||
/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
pub trait MetadataExt { |
|
||||||
/// Gain a reference to the underlying `stat` structure which contains
|
|
||||||
/// the raw information returned by the OS.
|
|
||||||
///
|
|
||||||
/// The contents of the returned `stat` are **not** consistent across
|
|
||||||
/// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
|
|
||||||
/// cross-Unix abstractions contained within the raw stat.
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
#[rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "deprecated in favor of the accessor \ |
|
||||||
methods of this trait")] |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat; |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_dev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ino(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mode(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_nlink(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_uid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_gid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_rdev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_size(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blksize(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blocks(&self) -> u64; |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
impl MetadataExt for Metadata { |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat { |
|
||||||
unsafe { |
|
||||||
&*(self.as_inner().as_inner() as *const libc::stat64 |
|
||||||
as *const raw::stat) |
|
||||||
} |
|
||||||
} |
|
||||||
fn st_dev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_dev as u64 |
|
||||||
} |
|
||||||
fn st_ino(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_ino as u64 |
|
||||||
} |
|
||||||
fn st_mode(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_mode as u32 |
|
||||||
} |
|
||||||
fn st_nlink(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_nlink as u64 |
|
||||||
} |
|
||||||
fn st_uid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_uid as u32 |
|
||||||
} |
|
||||||
fn st_gid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_gid as u32 |
|
||||||
} |
|
||||||
fn st_rdev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_rdev as u64 |
|
||||||
} |
|
||||||
fn st_size(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_size as u64 |
|
||||||
} |
|
||||||
fn st_atime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime as i64 |
|
||||||
} |
|
||||||
fn st_atime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_mtime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime as i64 |
|
||||||
} |
|
||||||
fn st_mtime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_ctime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime as i64 |
|
||||||
} |
|
||||||
fn st_ctime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_blksize(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blksize as u64 |
|
||||||
} |
|
||||||
fn st_blocks(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blocks as u64 |
|
||||||
} |
|
||||||
} |
|
@ -1,16 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Linux-specific definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
pub mod raw; |
|
||||||
pub mod fs; |
|
@ -1,81 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Emscripten-specific raw type definitions
|
|
||||||
//! This is basically exactly the same as the linux definitions,
|
|
||||||
//! except using the musl-specific stat64 structure in liblibc.
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
#![rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "these type aliases are no longer supported by \ |
|
||||||
the standard library, the `libc` crate on \ |
|
||||||
crates.io should be used instead for the correct \ |
|
||||||
definitions")] |
|
||||||
#![allow(deprecated)] |
|
||||||
|
|
||||||
use os::raw::{c_long, c_short, c_uint, c_ulong}; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32; |
|
||||||
|
|
||||||
#[stable(feature = "pthread_t", since = "1.8.0")] |
|
||||||
pub type pthread_t = c_ulong; |
|
||||||
|
|
||||||
#[doc(inline)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = c_long; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __pad1: c_short, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __st_ino: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __pad2: c_uint, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: time_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: time_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: time_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: u64, |
|
||||||
} |
|
@ -1,156 +0,0 @@ |
|||||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#![stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
use libc; |
|
||||||
|
|
||||||
use fs::Metadata; |
|
||||||
use sys_common::AsInner; |
|
||||||
|
|
||||||
#[allow(deprecated)] |
|
||||||
use os::freebsd::raw; |
|
||||||
|
|
||||||
/// OS-specific extensions to [`fs::Metadata`].
|
|
||||||
///
|
|
||||||
/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
pub trait MetadataExt { |
|
||||||
/// Gain a reference to the underlying `stat` structure which contains
|
|
||||||
/// the raw information returned by the OS.
|
|
||||||
///
|
|
||||||
/// The contents of the returned `stat` are **not** consistent across
|
|
||||||
/// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
|
|
||||||
/// cross-Unix abstractions contained within the raw stat.
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
#[rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "deprecated in favor of the accessor \ |
|
||||||
methods of this trait")] |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat; |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_dev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ino(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mode(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_nlink(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_uid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_gid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_rdev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_size(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_birthtime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_birthtime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blksize(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blocks(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_flags(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_gen(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_lspare(&self) -> u32; |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
impl MetadataExt for Metadata { |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat { |
|
||||||
unsafe { |
|
||||||
&*(self.as_inner().as_inner() as *const libc::stat |
|
||||||
as *const raw::stat) |
|
||||||
} |
|
||||||
} |
|
||||||
fn st_dev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_dev as u64 |
|
||||||
} |
|
||||||
fn st_ino(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_ino as u64 |
|
||||||
} |
|
||||||
fn st_mode(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_mode as u32 |
|
||||||
} |
|
||||||
fn st_nlink(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_nlink as u64 |
|
||||||
} |
|
||||||
fn st_uid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_uid as u32 |
|
||||||
} |
|
||||||
fn st_gid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_gid as u32 |
|
||||||
} |
|
||||||
fn st_rdev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_rdev as u64 |
|
||||||
} |
|
||||||
fn st_size(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_size as u64 |
|
||||||
} |
|
||||||
fn st_atime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime as i64 |
|
||||||
} |
|
||||||
fn st_atime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_mtime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime as i64 |
|
||||||
} |
|
||||||
fn st_mtime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_ctime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime as i64 |
|
||||||
} |
|
||||||
fn st_ctime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_birthtime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_birthtime as i64 |
|
||||||
} |
|
||||||
fn st_birthtime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_birthtime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_blksize(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blksize as u64 |
|
||||||
} |
|
||||||
fn st_blocks(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blocks as u64 |
|
||||||
} |
|
||||||
fn st_gen(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_gen as u32 |
|
||||||
} |
|
||||||
fn st_flags(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_flags as u32 |
|
||||||
} |
|
||||||
fn st_lspare(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_lspare as u32 |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
@ -1,16 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! FreeBSD-specific definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
pub mod raw; |
|
||||||
pub mod fs; |
|
@ -1,85 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! FreeBSD-specific raw type definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
#![rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "these type aliases are no longer supported by \ |
|
||||||
the standard library, the `libc` crate on \ |
|
||||||
crates.io should be used instead for the correct \ |
|
||||||
definitions")] |
|
||||||
#![allow(deprecated)] |
|
||||||
|
|
||||||
use os::raw::c_long; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type fflags_t = u32; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; |
|
||||||
|
|
||||||
#[stable(feature = "pthread_t", since = "1.8.0")] |
|
||||||
pub type pthread_t = usize; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: u16, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: u16, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_flags: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gen: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_lspare: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_birthtime: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_birthtime_nsec: c_long, |
|
||||||
#[cfg(target_arch = "x86")] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __unused: [u8; 8], |
|
||||||
} |
|
@ -1,105 +0,0 @@ |
|||||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#![stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
use fs::Metadata; |
|
||||||
use sys_common::AsInner; |
|
||||||
|
|
||||||
/// OS-specific extensions to [`fs::Metadata`].
|
|
||||||
///
|
|
||||||
/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
pub trait MetadataExt { |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_dev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ino(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mode(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_nlink(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_uid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_gid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_rdev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_size(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blksize(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blocks(&self) -> u64; |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
impl MetadataExt for Metadata { |
|
||||||
fn st_dev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_dev as u64 |
|
||||||
} |
|
||||||
fn st_ino(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_ino as u64 |
|
||||||
} |
|
||||||
fn st_mode(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_mode as u32 |
|
||||||
} |
|
||||||
fn st_nlink(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_nlink as u64 |
|
||||||
} |
|
||||||
fn st_uid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_uid as u32 |
|
||||||
} |
|
||||||
fn st_gid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_gid as u32 |
|
||||||
} |
|
||||||
fn st_rdev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_rdev as u64 |
|
||||||
} |
|
||||||
fn st_size(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_size as u64 |
|
||||||
} |
|
||||||
fn st_atime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime as i64 |
|
||||||
} |
|
||||||
fn st_atime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_mtime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime as i64 |
|
||||||
} |
|
||||||
fn st_mtime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_ctime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime as i64 |
|
||||||
} |
|
||||||
fn st_ctime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_blksize(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blksize as u64 |
|
||||||
} |
|
||||||
fn st_blocks(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blocks as u64 |
|
||||||
} |
|
||||||
} |
|
@ -1,16 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Fuchsia-specific definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
pub mod raw; |
|
||||||
pub mod fs; |
|
@ -1,270 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Fuchsia-specific raw type definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
#![rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "these type aliases are no longer supported by \ |
|
||||||
the standard library, the `libc` crate on \ |
|
||||||
crates.io should be used instead for the correct \ |
|
||||||
definitions")] |
|
||||||
#![allow(deprecated)] |
|
||||||
|
|
||||||
use os::raw::c_ulong; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32; |
|
||||||
|
|
||||||
#[stable(feature = "pthread_t", since = "1.8.0")] |
|
||||||
pub type pthread_t = c_ulong; |
|
||||||
|
|
||||||
#[doc(inline)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub use self::arch::{off_t, ino_t, nlink_t, blksize_t, blkcnt_t, stat, time_t}; |
|
||||||
|
|
||||||
#[cfg(any(target_arch = "x86",
|
|
||||||
target_arch = "le32", |
|
||||||
target_arch = "powerpc", |
|
||||||
target_arch = "arm"))] |
|
||||||
mod arch { |
|
||||||
use os::raw::{c_long, c_short, c_uint}; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __pad1: c_short, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __st_ino: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __pad2: c_uint, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: u64, |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(target_arch = "mips")] |
|
||||||
mod arch { |
|
||||||
use os::raw::{c_long, c_ulong}; |
|
||||||
|
|
||||||
#[cfg(target_env = "musl")] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = i64; |
|
||||||
#[cfg(not(target_env = "musl"))] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64; |
|
||||||
#[cfg(target_env = "musl")] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[cfg(not(target_env = "musl"))] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64; |
|
||||||
#[cfg(target_env = "musl")] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[cfg(not(target_env = "musl"))] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: c_ulong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_pad1: [c_long; 3], |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: c_ulong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_pad2: [c_long; 2], |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_pad5: [c_long; 14], |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(target_arch = "mips64")] |
|
||||||
mod arch { |
|
||||||
pub use libc::{off_t, ino_t, nlink_t, blksize_t, blkcnt_t, stat, time_t}; |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")] |
|
||||||
mod arch { |
|
||||||
use os::raw::{c_long, c_int}; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __pad1: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __pad2: c_int, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __unused: [c_int; 2], |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")] |
|
||||||
mod arch { |
|
||||||
use os::raw::{c_long, c_int}; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __pad0: c_int, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __unused: [c_long; 3], |
|
||||||
} |
|
||||||
} |
|
@ -1,140 +0,0 @@ |
|||||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#![stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
use libc; |
|
||||||
|
|
||||||
use fs::Metadata; |
|
||||||
use sys_common::AsInner; |
|
||||||
|
|
||||||
#[allow(deprecated)] |
|
||||||
use os::haiku::raw; |
|
||||||
|
|
||||||
/// OS-specific extensions to [`fs::Metadata`].
|
|
||||||
///
|
|
||||||
/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
pub trait MetadataExt { |
|
||||||
/// Gain a reference to the underlying `stat` structure which contains
|
|
||||||
/// the raw information returned by the OS.
|
|
||||||
///
|
|
||||||
/// The contents of the returned `stat` are **not** consistent across
|
|
||||||
/// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
|
|
||||||
/// cross-Unix abstractions contained within the raw stat.
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
#[rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "deprecated in favor of the accessor \ |
|
||||||
methods of this trait")] |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat; |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_dev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ino(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mode(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_nlink(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_uid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_gid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_rdev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_size(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_crtime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_crtime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blksize(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blocks(&self) -> u64; |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
impl MetadataExt for Metadata { |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat { |
|
||||||
unsafe { |
|
||||||
&*(self.as_inner().as_inner() as *const libc::stat |
|
||||||
as *const raw::stat) |
|
||||||
} |
|
||||||
} |
|
||||||
fn st_dev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_dev as u64 |
|
||||||
} |
|
||||||
fn st_ino(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_ino as u64 |
|
||||||
} |
|
||||||
fn st_mode(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_mode as u32 |
|
||||||
} |
|
||||||
fn st_nlink(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_nlink as u64 |
|
||||||
} |
|
||||||
fn st_uid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_uid as u32 |
|
||||||
} |
|
||||||
fn st_gid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_gid as u32 |
|
||||||
} |
|
||||||
fn st_rdev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_rdev as u64 |
|
||||||
} |
|
||||||
fn st_size(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_size as u64 |
|
||||||
} |
|
||||||
fn st_atime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime as i64 |
|
||||||
} |
|
||||||
fn st_atime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_mtime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime as i64 |
|
||||||
} |
|
||||||
fn st_mtime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_ctime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime as i64 |
|
||||||
} |
|
||||||
fn st_ctime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_crtime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_crtime as i64 |
|
||||||
} |
|
||||||
fn st_crtime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_crtime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_blksize(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blksize as u64 |
|
||||||
} |
|
||||||
fn st_blocks(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blocks as u64 |
|
||||||
} |
|
||||||
} |
|
@ -1,16 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Haiku-specific definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
pub mod raw; |
|
||||||
pub mod fs; |
|
@ -1,74 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Haiku-specific raw type definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
#![allow(deprecated)] |
|
||||||
|
|
||||||
use os::raw::{c_long}; |
|
||||||
use os::unix::raw::{uid_t, gid_t}; |
|
||||||
|
|
||||||
// Use the direct definition of usize, instead of uintptr_t like in libc
|
|
||||||
#[stable(feature = "pthread_t", since = "1.8.0")] pub type pthread_t = usize; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = i64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = i32; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = i32; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = i64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = i32; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = i64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i32; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: dev_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: ino_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: mode_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: nlink_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: uid_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: gid_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: off_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: dev_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: blksize_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: time_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: time_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: time_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_crtime: time_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_crtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_type: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: blkcnt_t, |
|
||||||
} |
|
@ -1,389 +0,0 @@ |
|||||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#![stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
use libc; |
|
||||||
|
|
||||||
use fs::Metadata; |
|
||||||
use sys_common::AsInner; |
|
||||||
|
|
||||||
#[allow(deprecated)] |
|
||||||
use os::hermit::raw; |
|
||||||
|
|
||||||
/// OS-specific extensions to [`fs::Metadata`].
|
|
||||||
///
|
|
||||||
/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
pub trait MetadataExt { |
|
||||||
/// Gain a reference to the underlying `stat` structure which contains
|
|
||||||
/// the raw information returned by the OS.
|
|
||||||
///
|
|
||||||
/// The contents of the returned [`stat`] are **not** consistent across
|
|
||||||
/// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
|
|
||||||
/// cross-Unix abstractions contained within the raw stat.
|
|
||||||
///
|
|
||||||
/// [`stat`]: ../../../../std/os/linux/raw/struct.stat.html
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// let stat = meta.as_raw_stat();
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
#[rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "deprecated in favor of the accessor \ |
|
||||||
methods of this trait")] |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat; |
|
||||||
|
|
||||||
/// Returns the device ID on which this file resides.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_dev());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_dev(&self) -> u64; |
|
||||||
/// Returns the inode number.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_ino());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ino(&self) -> u64; |
|
||||||
/// Returns the file type and mode.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_mode());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mode(&self) -> u32; |
|
||||||
/// Returns the number of hard links to file.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_nlink());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_nlink(&self) -> u64; |
|
||||||
/// Returns the user ID of the file owner.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_uid());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_uid(&self) -> u32; |
|
||||||
/// Returns the group ID of the file owner.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_gid());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_gid(&self) -> u32; |
|
||||||
/// Returns the device ID that this file represents. Only relevant for special file.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_rdev());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_rdev(&self) -> u64; |
|
||||||
/// Returns the size of the file (if it is a regular file or a symbolic link) in bytes.
|
|
||||||
///
|
|
||||||
/// The size of a symbolic link is the length of the pathname it contains,
|
|
||||||
/// without a terminating null byte.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_size());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_size(&self) -> u64; |
|
||||||
/// Returns the last access time.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_atime());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime(&self) -> i64; |
|
||||||
/// Returns the last access time, nano seconds part.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_atime_nsec());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime_nsec(&self) -> i64; |
|
||||||
/// Returns the last modification time.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_mtime());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime(&self) -> i64; |
|
||||||
/// Returns the last modification time, nano seconds part.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_mtime_nsec());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime_nsec(&self) -> i64; |
|
||||||
/// Returns the last status change time.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_ctime());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime(&self) -> i64; |
|
||||||
/// Returns the last status change time, nano seconds part.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_ctime_nsec());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime_nsec(&self) -> i64; |
|
||||||
/// Returns the "preferred" blocksize for efficient filesystem I/O.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_blksize());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blksize(&self) -> u64; |
|
||||||
/// Returns the number of blocks allocated to the file, 512-byte units.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_blocks());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blocks(&self) -> u64; |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
impl MetadataExt for Metadata { |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat { |
|
||||||
unsafe { |
|
||||||
&*(self.as_inner().as_inner() as *const libc::stat64 |
|
||||||
as *const raw::stat) |
|
||||||
} |
|
||||||
} |
|
||||||
fn st_dev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_dev as u64 |
|
||||||
} |
|
||||||
fn st_ino(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_ino as u64 |
|
||||||
} |
|
||||||
fn st_mode(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_mode as u32 |
|
||||||
} |
|
||||||
fn st_nlink(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_nlink as u64 |
|
||||||
} |
|
||||||
fn st_uid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_uid as u32 |
|
||||||
} |
|
||||||
fn st_gid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_gid as u32 |
|
||||||
} |
|
||||||
fn st_rdev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_rdev as u64 |
|
||||||
} |
|
||||||
fn st_size(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_size as u64 |
|
||||||
} |
|
||||||
fn st_atime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime as i64 |
|
||||||
} |
|
||||||
fn st_atime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_mtime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime as i64 |
|
||||||
} |
|
||||||
fn st_mtime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_ctime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime as i64 |
|
||||||
} |
|
||||||
fn st_ctime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_blksize(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blksize as u64 |
|
||||||
} |
|
||||||
fn st_blocks(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blocks as u64 |
|
||||||
} |
|
||||||
} |
|
@ -1,16 +0,0 @@ |
|||||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! HermitCore-specific definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
pub mod raw; |
|
||||||
pub mod fs; |
|
@ -1,27 +0,0 @@ |
|||||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! HermitCore-specific raw type definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
#![rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "these type aliases are no longer supported by \ |
|
||||||
the standard library, the `libc` crate on \ |
|
||||||
crates.io should be used instead for the correct \ |
|
||||||
definitions")] |
|
||||||
#![allow(deprecated)] |
|
||||||
#![allow(missing_debug_implementations)] |
|
||||||
|
|
||||||
#[stable(feature = "pthread_t", since = "1.8.0")] |
|
||||||
pub use libc::pthread_t; |
|
||||||
|
|
||||||
#[doc(inline)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub use libc::{dev_t, mode_t, off_t, ino_t, nlink_t, blksize_t, blkcnt_t, stat, time_t}; |
|
@ -1,393 +0,0 @@ |
|||||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#![stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
use libc; |
|
||||||
|
|
||||||
use fs::Metadata; |
|
||||||
use sys_common::AsInner; |
|
||||||
|
|
||||||
#[allow(deprecated)] |
|
||||||
use os::horizon::raw; |
|
||||||
|
|
||||||
/// OS-specific extensions to [`fs::Metadata`].
|
|
||||||
///
|
|
||||||
/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
pub trait MetadataExt { |
|
||||||
/// Gain a reference to the underlying `stat` structure which contains
|
|
||||||
/// the raw information returned by the OS.
|
|
||||||
///
|
|
||||||
/// The contents of the returned [`stat`] are **not** consistent across
|
|
||||||
/// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
|
|
||||||
/// cross-Unix abstractions contained within the raw stat.
|
|
||||||
///
|
|
||||||
/// [`stat`]: ../../../../std/os/linux/raw/struct.stat.html
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// let stat = meta.as_raw_stat();
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
#[rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "deprecated in favor of the accessor \ |
|
||||||
methods of this trait")] |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat; |
|
||||||
|
|
||||||
/// Returns the device ID on which this file resides.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_dev());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_dev(&self) -> u64; |
|
||||||
/// Returns the inode number.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_ino());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ino(&self) -> u64; |
|
||||||
/// Returns the file type and mode.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_mode());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mode(&self) -> u32; |
|
||||||
/// Returns the number of hard links to file.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_nlink());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_nlink(&self) -> u64; |
|
||||||
/// Returns the user ID of the file owner.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_uid());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_uid(&self) -> u32; |
|
||||||
/// Returns the group ID of the file owner.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_gid());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_gid(&self) -> u32; |
|
||||||
/// Returns the device ID that this file represents. Only relevant for special file.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_rdev());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_rdev(&self) -> u64; |
|
||||||
/// Returns the size of the file (if it is a regular file or a symbolic link) in bytes.
|
|
||||||
///
|
|
||||||
/// The size of a symbolic link is the length of the pathname it contains,
|
|
||||||
/// without a terminating null byte.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_size());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_size(&self) -> u64; |
|
||||||
/// Returns the last access time.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_atime());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime(&self) -> i64; |
|
||||||
/// Returns the last access time, nano seconds part.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_atime_nsec());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime_nsec(&self) -> i64; |
|
||||||
/// Returns the last modification time.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_mtime());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime(&self) -> i64; |
|
||||||
/// Returns the last modification time, nano seconds part.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_mtime_nsec());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime_nsec(&self) -> i64; |
|
||||||
/// Returns the last status change time.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_ctime());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime(&self) -> i64; |
|
||||||
/// Returns the last status change time, nano seconds part.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_ctime_nsec());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime_nsec(&self) -> i64; |
|
||||||
/// Returns the "preferred" blocksize for efficient filesystem I/O.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_blksize());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blksize(&self) -> u64; |
|
||||||
/// Returns the number of blocks allocated to the file, 512-byte units.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_blocks());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blocks(&self) -> u64; |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
impl MetadataExt for Metadata { |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat { |
|
||||||
unsafe { |
|
||||||
&*(self.as_inner().as_inner() as *const libc::stat |
|
||||||
as *const raw::stat) |
|
||||||
} |
|
||||||
} |
|
||||||
fn st_dev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_dev as u64 |
|
||||||
} |
|
||||||
fn st_ino(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_ino as u64 |
|
||||||
} |
|
||||||
fn st_mode(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_mode as u32 |
|
||||||
} |
|
||||||
fn st_nlink(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_nlink as u64 |
|
||||||
} |
|
||||||
fn st_uid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_uid as u32 |
|
||||||
} |
|
||||||
fn st_gid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_gid as u32 |
|
||||||
} |
|
||||||
fn st_rdev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_rdev as u64 |
|
||||||
} |
|
||||||
fn st_size(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_size as u64 |
|
||||||
} |
|
||||||
fn st_atime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime as i64 |
|
||||||
} |
|
||||||
fn st_atime_nsec(&self) -> i64 { |
|
||||||
//self.as_inner().as_inner().st_atime_nsec as i64
|
|
||||||
0i64 |
|
||||||
} |
|
||||||
fn st_mtime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime as i64 |
|
||||||
} |
|
||||||
fn st_mtime_nsec(&self) -> i64 { |
|
||||||
//self.as_inner().as_inner().st_mtime_nsec as i64
|
|
||||||
0i64 |
|
||||||
} |
|
||||||
fn st_ctime(&self) -> i64 { |
|
||||||
//self.as_inner().as_inner().st_ctime as i64
|
|
||||||
0i64 |
|
||||||
} |
|
||||||
fn st_ctime_nsec(&self) -> i64 { |
|
||||||
//self.as_inner().as_inner().st_ctime_nsec as i64
|
|
||||||
0i64 |
|
||||||
} |
|
||||||
fn st_blksize(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blksize as u64 |
|
||||||
} |
|
||||||
fn st_blocks(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blocks as u64 |
|
||||||
} |
|
||||||
} |
|
@ -1,16 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Linux-specific definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
pub mod raw; |
|
||||||
pub mod fs; |
|
@ -1,275 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Linux-specific raw type definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
#![rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "these type aliases are no longer supported by \ |
|
||||||
the standard library, the `libc` crate on \ |
|
||||||
crates.io should be used instead for the correct \ |
|
||||||
definitions")] |
|
||||||
#![allow(deprecated)] |
|
||||||
#![allow(missing_debug_implementations)] |
|
||||||
|
|
||||||
use os::raw::c_ulong; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32; |
|
||||||
|
|
||||||
#[stable(feature = "pthread_t", since = "1.8.0")] |
|
||||||
pub type pthread_t = c_ulong; |
|
||||||
|
|
||||||
#[doc(inline)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub use self::arch::{off_t, ino_t, nlink_t, blksize_t, blkcnt_t, stat, time_t}; |
|
||||||
|
|
||||||
#[cfg(any(target_arch = "x86",
|
|
||||||
target_arch = "le32", |
|
||||||
target_arch = "powerpc", |
|
||||||
target_arch = "arm", |
|
||||||
target_arch = "asmjs", |
|
||||||
target_arch = "wasm32"))] |
|
||||||
mod arch { |
|
||||||
use os::raw::{c_long, c_short, c_uint}; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __pad1: c_short, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __st_ino: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __pad2: c_uint, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: u64, |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(target_arch = "mips")] |
|
||||||
mod arch { |
|
||||||
use os::raw::{c_long, c_ulong}; |
|
||||||
|
|
||||||
#[cfg(target_env = "musl")] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = i64; |
|
||||||
#[cfg(not(target_env = "musl"))] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64; |
|
||||||
#[cfg(target_env = "musl")] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[cfg(not(target_env = "musl"))] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64; |
|
||||||
#[cfg(target_env = "musl")] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[cfg(not(target_env = "musl"))] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: c_ulong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_pad1: [c_long; 3], |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: c_ulong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_pad2: [c_long; 2], |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_pad5: [c_long; 14], |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(any(target_arch = "mips64",
|
|
||||||
target_arch = "s390x", |
|
||||||
target_arch = "sparc64"))] |
|
||||||
mod arch { |
|
||||||
pub use libc::{off_t, ino_t, nlink_t, blksize_t, blkcnt_t, stat, time_t}; |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")] |
|
||||||
mod arch { |
|
||||||
use os::raw::{c_long, c_int}; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __pad1: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __pad2: c_int, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __unused: [c_int; 2], |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(any(target_arch = "x86_64", target_arch = "powerpc64"))] |
|
||||||
mod arch { |
|
||||||
use os::raw::{c_long, c_int}; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __pad0: c_int, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __unused: [c_long; 3], |
|
||||||
} |
|
||||||
} |
|
@ -1,156 +0,0 @@ |
|||||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#![stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
use libc; |
|
||||||
|
|
||||||
use fs::Metadata; |
|
||||||
use sys_common::AsInner; |
|
||||||
|
|
||||||
#[allow(deprecated)] |
|
||||||
use os::ios::raw; |
|
||||||
|
|
||||||
/// OS-specific extensions to [`fs::Metadata`].
|
|
||||||
///
|
|
||||||
/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
pub trait MetadataExt { |
|
||||||
/// Gain a reference to the underlying `stat` structure which contains
|
|
||||||
/// the raw information returned by the OS.
|
|
||||||
///
|
|
||||||
/// The contents of the returned `stat` are **not** consistent across
|
|
||||||
/// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
|
|
||||||
/// cross-Unix abstractions contained within the raw stat.
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
#[rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "deprecated in favor of the accessor \ |
|
||||||
methods of this trait")] |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat; |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_dev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ino(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mode(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_nlink(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_uid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_gid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_rdev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_size(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_birthtime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_birthtime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blksize(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blocks(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_flags(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_gen(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_lspare(&self) -> u32; |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
impl MetadataExt for Metadata { |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat { |
|
||||||
unsafe { |
|
||||||
&*(self.as_inner().as_inner() as *const libc::stat |
|
||||||
as *const raw::stat) |
|
||||||
} |
|
||||||
} |
|
||||||
fn st_dev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_dev as u64 |
|
||||||
} |
|
||||||
fn st_ino(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_ino as u64 |
|
||||||
} |
|
||||||
fn st_mode(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_mode as u32 |
|
||||||
} |
|
||||||
fn st_nlink(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_nlink as u64 |
|
||||||
} |
|
||||||
fn st_uid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_uid as u32 |
|
||||||
} |
|
||||||
fn st_gid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_gid as u32 |
|
||||||
} |
|
||||||
fn st_rdev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_rdev as u64 |
|
||||||
} |
|
||||||
fn st_size(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_size as u64 |
|
||||||
} |
|
||||||
fn st_atime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime as i64 |
|
||||||
} |
|
||||||
fn st_atime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_mtime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime as i64 |
|
||||||
} |
|
||||||
fn st_mtime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_ctime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime as i64 |
|
||||||
} |
|
||||||
fn st_ctime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_birthtime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_birthtime as i64 |
|
||||||
} |
|
||||||
fn st_birthtime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_birthtime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_blksize(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blksize as u64 |
|
||||||
} |
|
||||||
fn st_blocks(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blocks as u64 |
|
||||||
} |
|
||||||
fn st_gen(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_gen as u32 |
|
||||||
} |
|
||||||
fn st_flags(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_flags as u32 |
|
||||||
} |
|
||||||
fn st_lspare(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_lspare as u32 |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
@ -1,16 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! iOS-specific definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
pub mod raw; |
|
||||||
pub mod fs; |
|
@ -1,83 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! iOS-specific raw type definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
#![rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "these type aliases are no longer supported by \ |
|
||||||
the standard library, the `libc` crate on \ |
|
||||||
crates.io should be used instead for the correct \ |
|
||||||
definitions")] |
|
||||||
#![allow(deprecated)] |
|
||||||
|
|
||||||
use os::raw::c_long; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; |
|
||||||
|
|
||||||
#[stable(feature = "pthread_t", since = "1.8.0")] |
|
||||||
pub type pthread_t = usize; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: u16, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: u16, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_birthtime: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_birthtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_flags: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gen: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_lspare: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_qspare: [i64; 2], |
|
||||||
} |
|
@ -1,389 +0,0 @@ |
|||||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#![stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
use libc; |
|
||||||
|
|
||||||
use fs::Metadata; |
|
||||||
use sys_common::AsInner; |
|
||||||
|
|
||||||
#[allow(deprecated)] |
|
||||||
use os::linux::raw; |
|
||||||
|
|
||||||
/// OS-specific extensions to [`fs::Metadata`].
|
|
||||||
///
|
|
||||||
/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
pub trait MetadataExt { |
|
||||||
/// Gain a reference to the underlying `stat` structure which contains
|
|
||||||
/// the raw information returned by the OS.
|
|
||||||
///
|
|
||||||
/// The contents of the returned [`stat`] are **not** consistent across
|
|
||||||
/// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
|
|
||||||
/// cross-Unix abstractions contained within the raw stat.
|
|
||||||
///
|
|
||||||
/// [`stat`]: ../../../../std/os/linux/raw/struct.stat.html
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// let stat = meta.as_raw_stat();
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
#[rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "deprecated in favor of the accessor \ |
|
||||||
methods of this trait")] |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat; |
|
||||||
|
|
||||||
/// Returns the device ID on which this file resides.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_dev());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_dev(&self) -> u64; |
|
||||||
/// Returns the inode number.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_ino());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ino(&self) -> u64; |
|
||||||
/// Returns the file type and mode.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_mode());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mode(&self) -> u32; |
|
||||||
/// Returns the number of hard links to file.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_nlink());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_nlink(&self) -> u64; |
|
||||||
/// Returns the user ID of the file owner.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_uid());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_uid(&self) -> u32; |
|
||||||
/// Returns the group ID of the file owner.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_gid());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_gid(&self) -> u32; |
|
||||||
/// Returns the device ID that this file represents. Only relevant for special file.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_rdev());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_rdev(&self) -> u64; |
|
||||||
/// Returns the size of the file (if it is a regular file or a symbolic link) in bytes.
|
|
||||||
///
|
|
||||||
/// The size of a symbolic link is the length of the pathname it contains,
|
|
||||||
/// without a terminating null byte.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_size());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_size(&self) -> u64; |
|
||||||
/// Returns the last access time.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_atime());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime(&self) -> i64; |
|
||||||
/// Returns the last access time, nano seconds part.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_atime_nsec());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime_nsec(&self) -> i64; |
|
||||||
/// Returns the last modification time.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_mtime());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime(&self) -> i64; |
|
||||||
/// Returns the last modification time, nano seconds part.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_mtime_nsec());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime_nsec(&self) -> i64; |
|
||||||
/// Returns the last status change time.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_ctime());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime(&self) -> i64; |
|
||||||
/// Returns the last status change time, nano seconds part.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_ctime_nsec());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime_nsec(&self) -> i64; |
|
||||||
/// Returns the "preferred" blocksize for efficient filesystem I/O.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_blksize());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blksize(&self) -> u64; |
|
||||||
/// Returns the number of blocks allocated to the file, 512-byte units.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs;
|
|
||||||
/// use std::io;
|
|
||||||
/// use std::os::linux::fs::MetadataExt;
|
|
||||||
///
|
|
||||||
/// fn main() -> io::Result<()> {
|
|
||||||
/// let meta = fs::metadata("some_file")?;
|
|
||||||
/// println!("{}", meta.st_blocks());
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blocks(&self) -> u64; |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
impl MetadataExt for Metadata { |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat { |
|
||||||
unsafe { |
|
||||||
&*(self.as_inner().as_inner() as *const libc::stat64 |
|
||||||
as *const raw::stat) |
|
||||||
} |
|
||||||
} |
|
||||||
fn st_dev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_dev as u64 |
|
||||||
} |
|
||||||
fn st_ino(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_ino as u64 |
|
||||||
} |
|
||||||
fn st_mode(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_mode as u32 |
|
||||||
} |
|
||||||
fn st_nlink(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_nlink as u64 |
|
||||||
} |
|
||||||
fn st_uid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_uid as u32 |
|
||||||
} |
|
||||||
fn st_gid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_gid as u32 |
|
||||||
} |
|
||||||
fn st_rdev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_rdev as u64 |
|
||||||
} |
|
||||||
fn st_size(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_size as u64 |
|
||||||
} |
|
||||||
fn st_atime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime as i64 |
|
||||||
} |
|
||||||
fn st_atime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_mtime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime as i64 |
|
||||||
} |
|
||||||
fn st_mtime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_ctime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime as i64 |
|
||||||
} |
|
||||||
fn st_ctime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_blksize(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blksize as u64 |
|
||||||
} |
|
||||||
fn st_blocks(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blocks as u64 |
|
||||||
} |
|
||||||
} |
|
@ -1,16 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Linux-specific definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
pub mod raw; |
|
||||||
pub mod fs; |
|
@ -1,275 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Linux-specific raw type definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
#![rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "these type aliases are no longer supported by \ |
|
||||||
the standard library, the `libc` crate on \ |
|
||||||
crates.io should be used instead for the correct \ |
|
||||||
definitions")] |
|
||||||
#![allow(deprecated)] |
|
||||||
#![allow(missing_debug_implementations)] |
|
||||||
|
|
||||||
use os::raw::c_ulong; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32; |
|
||||||
|
|
||||||
#[stable(feature = "pthread_t", since = "1.8.0")] |
|
||||||
pub type pthread_t = c_ulong; |
|
||||||
|
|
||||||
#[doc(inline)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub use self::arch::{off_t, ino_t, nlink_t, blksize_t, blkcnt_t, stat, time_t}; |
|
||||||
|
|
||||||
#[cfg(any(target_arch = "x86",
|
|
||||||
target_arch = "le32", |
|
||||||
target_arch = "powerpc", |
|
||||||
target_arch = "arm", |
|
||||||
target_arch = "asmjs", |
|
||||||
target_arch = "wasm32"))] |
|
||||||
mod arch { |
|
||||||
use os::raw::{c_long, c_short, c_uint}; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __pad1: c_short, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __st_ino: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __pad2: c_uint, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: u64, |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(target_arch = "mips")] |
|
||||||
mod arch { |
|
||||||
use os::raw::{c_long, c_ulong}; |
|
||||||
|
|
||||||
#[cfg(target_env = "musl")] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = i64; |
|
||||||
#[cfg(not(target_env = "musl"))] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64; |
|
||||||
#[cfg(target_env = "musl")] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[cfg(not(target_env = "musl"))] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64; |
|
||||||
#[cfg(target_env = "musl")] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[cfg(not(target_env = "musl"))] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: c_ulong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_pad1: [c_long; 3], |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: c_ulong, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_pad2: [c_long; 2], |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_pad5: [c_long; 14], |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(any(target_arch = "mips64",
|
|
||||||
target_arch = "s390x", |
|
||||||
target_arch = "sparc64"))] |
|
||||||
mod arch { |
|
||||||
pub use libc::{off_t, ino_t, nlink_t, blksize_t, blkcnt_t, stat, time_t}; |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")] |
|
||||||
mod arch { |
|
||||||
use os::raw::{c_long, c_int}; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __pad1: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __pad2: c_int, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __unused: [c_int; 2], |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(any(target_arch = "x86_64", target_arch = "powerpc64"))] |
|
||||||
mod arch { |
|
||||||
use os::raw::{c_long, c_int}; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __pad0: c_int, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub __unused: [c_long; 3], |
|
||||||
} |
|
||||||
} |
|
@ -1,162 +0,0 @@ |
|||||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#![stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
use libc; |
|
||||||
|
|
||||||
use fs::Metadata; |
|
||||||
use sys_common::AsInner; |
|
||||||
|
|
||||||
#[allow(deprecated)] |
|
||||||
use os::macos::raw; |
|
||||||
|
|
||||||
/// OS-specific extensions to [`fs::Metadata`].
|
|
||||||
///
|
|
||||||
/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
pub trait MetadataExt { |
|
||||||
/// Gain a reference to the underlying `stat` structure which contains
|
|
||||||
/// the raw information returned by the OS.
|
|
||||||
///
|
|
||||||
/// The contents of the returned `stat` are **not** consistent across
|
|
||||||
/// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
|
|
||||||
/// cross-Unix abstractions contained within the raw stat.
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
#[rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "deprecated in favor of the accessor \ |
|
||||||
methods of this trait")] |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat; |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_dev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ino(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mode(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_nlink(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_uid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_gid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_rdev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_size(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_birthtime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_birthtime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blksize(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blocks(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_flags(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_gen(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_lspare(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_qspare(&self) -> [u64; 2]; |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
impl MetadataExt for Metadata { |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat { |
|
||||||
unsafe { |
|
||||||
&*(self.as_inner().as_inner() as *const libc::stat |
|
||||||
as *const raw::stat) |
|
||||||
} |
|
||||||
} |
|
||||||
fn st_dev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_dev as u64 |
|
||||||
} |
|
||||||
fn st_ino(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_ino as u64 |
|
||||||
} |
|
||||||
fn st_mode(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_mode as u32 |
|
||||||
} |
|
||||||
fn st_nlink(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_nlink as u64 |
|
||||||
} |
|
||||||
fn st_uid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_uid as u32 |
|
||||||
} |
|
||||||
fn st_gid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_gid as u32 |
|
||||||
} |
|
||||||
fn st_rdev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_rdev as u64 |
|
||||||
} |
|
||||||
fn st_size(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_size as u64 |
|
||||||
} |
|
||||||
fn st_atime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime as i64 |
|
||||||
} |
|
||||||
fn st_atime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_mtime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime as i64 |
|
||||||
} |
|
||||||
fn st_mtime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_ctime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime as i64 |
|
||||||
} |
|
||||||
fn st_ctime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_birthtime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_birthtime as i64 |
|
||||||
} |
|
||||||
fn st_birthtime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_birthtime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_blksize(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blksize as u64 |
|
||||||
} |
|
||||||
fn st_blocks(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blocks as u64 |
|
||||||
} |
|
||||||
fn st_gen(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_gen as u32 |
|
||||||
} |
|
||||||
fn st_flags(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_flags as u32 |
|
||||||
} |
|
||||||
fn st_lspare(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_lspare as u32 |
|
||||||
} |
|
||||||
fn st_qspare(&self) -> [u64; 2] { |
|
||||||
let qspare = self.as_inner().as_inner().st_qspare; |
|
||||||
[qspare[0] as u64, qspare[1] as u64] |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
@ -1,16 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! macOS-specific definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
pub mod raw; |
|
||||||
pub mod fs; |
|
@ -1,83 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! macOS-specific raw type definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
#![rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "these type aliases are no longer supported by \ |
|
||||||
the standard library, the `libc` crate on \ |
|
||||||
crates.io should be used instead for the correct \ |
|
||||||
definitions")] |
|
||||||
#![allow(deprecated)] |
|
||||||
|
|
||||||
use os::raw::c_long; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; |
|
||||||
|
|
||||||
#[stable(feature = "pthread_t", since = "1.8.0")] |
|
||||||
pub type pthread_t = usize; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: u16, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: u16, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_birthtime: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_birthtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_flags: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gen: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_lspare: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_qspare: [i64; 2], |
|
||||||
} |
|
@ -1,67 +0,0 @@ |
|||||||
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! OS-specific functionality.
|
|
||||||
|
|
||||||
#![stable(feature = "os", since = "1.0.0")] |
|
||||||
#![allow(missing_docs, bad_style, missing_debug_implementations)] |
|
||||||
|
|
||||||
cfg_if! { |
|
||||||
if #[cfg(dox)] { |
|
||||||
|
|
||||||
// When documenting libstd we want to show unix/windows/linux modules as
|
|
||||||
// these are the "main modules" that are used across platforms. This
|
|
||||||
// should help show platform-specific functionality in a hopefully
|
|
||||||
// cross-platform way in the documentation
|
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use sys::unix_ext as unix; |
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use sys::windows_ext as windows; |
|
||||||
|
|
||||||
#[doc(cfg(target_os = "linux"))] |
|
||||||
pub mod linux; |
|
||||||
|
|
||||||
} else { |
|
||||||
|
|
||||||
// If we're not documenting libstd then we just expose everything as we
|
|
||||||
// otherwise would.
|
|
||||||
|
|
||||||
#[cfg(target_os = "android")] pub mod android; |
|
||||||
#[cfg(target_os = "bitrig")] pub mod bitrig; |
|
||||||
#[cfg(target_os = "dragonfly")] pub mod dragonfly; |
|
||||||
#[cfg(target_os = "freebsd")] pub mod freebsd; |
|
||||||
#[cfg(target_os = "haiku")] pub mod haiku; |
|
||||||
#[cfg(target_os = "ios")] pub mod ios; |
|
||||||
#[cfg(target_os = "macos")] pub mod macos; |
|
||||||
#[cfg(target_os = "netbsd")] pub mod netbsd; |
|
||||||
#[cfg(target_os = "openbsd")] pub mod openbsd; |
|
||||||
#[cfg(target_os = "solaris")] pub mod solaris; |
|
||||||
#[cfg(target_os = "emscripten")] pub mod emscripten; |
|
||||||
#[cfg(target_os = "fuchsia")] pub mod fuchsia; |
|
||||||
#[cfg(target_os = "hermit")] pub mod hermit; |
|
||||||
#[cfg(target_os = "horizon")] pub mod horizon; |
|
||||||
|
|
||||||
#[cfg(any(target_os = "redox", unix))] |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use sys::ext as unix; |
|
||||||
|
|
||||||
#[cfg(windows)] |
|
||||||
#[stable(feature = "rust1", since = "1.0.0")] |
|
||||||
pub use sys::ext as windows; |
|
||||||
|
|
||||||
#[cfg(any(target_os = "linux", target_os = "l4re"))] |
|
||||||
pub mod linux; |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
pub mod raw; |
|
@ -1,151 +0,0 @@ |
|||||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#![stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
use libc; |
|
||||||
|
|
||||||
use fs::Metadata; |
|
||||||
use sys_common::AsInner; |
|
||||||
|
|
||||||
#[allow(deprecated)] |
|
||||||
use os::netbsd::raw; |
|
||||||
|
|
||||||
/// OS-specific extensions to [`fs::Metadata`].
|
|
||||||
///
|
|
||||||
/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
pub trait MetadataExt { |
|
||||||
/// Gain a reference to the underlying `stat` structure which contains
|
|
||||||
/// the raw information returned by the OS.
|
|
||||||
///
|
|
||||||
/// The contents of the returned `stat` are **not** consistent across
|
|
||||||
/// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
|
|
||||||
/// cross-Unix abstractions contained within the raw stat.
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
#[rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "deprecated in favor of the accessor \ |
|
||||||
methods of this trait")] |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat; |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_dev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ino(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mode(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_nlink(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_uid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_gid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_rdev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_size(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_birthtime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_birthtime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blksize(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blocks(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_flags(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_gen(&self) -> u32; |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
impl MetadataExt for Metadata { |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat { |
|
||||||
unsafe { |
|
||||||
&*(self.as_inner().as_inner() as *const libc::stat |
|
||||||
as *const raw::stat) |
|
||||||
} |
|
||||||
} |
|
||||||
fn st_dev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_dev as u64 |
|
||||||
} |
|
||||||
fn st_ino(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_ino as u64 |
|
||||||
} |
|
||||||
fn st_mode(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_mode as u32 |
|
||||||
} |
|
||||||
fn st_nlink(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_nlink as u64 |
|
||||||
} |
|
||||||
fn st_uid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_uid as u32 |
|
||||||
} |
|
||||||
fn st_gid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_gid as u32 |
|
||||||
} |
|
||||||
fn st_rdev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_rdev as u64 |
|
||||||
} |
|
||||||
fn st_size(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_size as u64 |
|
||||||
} |
|
||||||
fn st_atime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime as i64 |
|
||||||
} |
|
||||||
fn st_atime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atimensec as i64 |
|
||||||
} |
|
||||||
fn st_mtime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime as i64 |
|
||||||
} |
|
||||||
fn st_mtime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtimensec as i64 |
|
||||||
} |
|
||||||
fn st_ctime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime as i64 |
|
||||||
} |
|
||||||
fn st_ctime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctimensec as i64 |
|
||||||
} |
|
||||||
fn st_birthtime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_birthtime as i64 |
|
||||||
} |
|
||||||
fn st_birthtime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_birthtimensec as i64 |
|
||||||
} |
|
||||||
fn st_blksize(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blksize as u64 |
|
||||||
} |
|
||||||
fn st_blocks(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blocks as u64 |
|
||||||
} |
|
||||||
fn st_gen(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_gen as u32 |
|
||||||
} |
|
||||||
fn st_flags(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_flags as u32 |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
@ -1,16 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! OpenBSD-specific definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
pub mod raw; |
|
||||||
pub mod fs; |
|
@ -1,82 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! NetBSD-specific raw type definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
#![rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "these type aliases are no longer supported by \ |
|
||||||
the standard library, the `libc` crate on \ |
|
||||||
crates.io should be used instead for the correct \ |
|
||||||
definitions")] |
|
||||||
#![allow(deprecated)] |
|
||||||
|
|
||||||
use os::raw::c_long; |
|
||||||
use os::unix::raw::{uid_t, gid_t}; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type fflags_t = u32; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; |
|
||||||
|
|
||||||
#[stable(feature = "pthread_t", since = "1.8.0")] |
|
||||||
pub type pthread_t = usize; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: uid_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: gid_t, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_birthtime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_birthtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_flags: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gen: u32, |
|
||||||
st_spare: [u32; 2], |
|
||||||
} |
|
@ -1,151 +0,0 @@ |
|||||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#![stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
use libc; |
|
||||||
|
|
||||||
use fs::Metadata; |
|
||||||
use sys_common::AsInner; |
|
||||||
|
|
||||||
#[allow(deprecated)] |
|
||||||
use os::openbsd::raw; |
|
||||||
|
|
||||||
/// OS-specific extensions to [`fs::Metadata`].
|
|
||||||
///
|
|
||||||
/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
pub trait MetadataExt { |
|
||||||
/// Gain a reference to the underlying `stat` structure which contains
|
|
||||||
/// the raw information returned by the OS.
|
|
||||||
///
|
|
||||||
/// The contents of the returned `stat` are **not** consistent across
|
|
||||||
/// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
|
|
||||||
/// cross-Unix abstractions contained within the raw stat.
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
#[rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "deprecated in favor of the accessor \ |
|
||||||
methods of this trait")] |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat; |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_dev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ino(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mode(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_nlink(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_uid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_gid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_rdev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_size(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_birthtime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_birthtime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blksize(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blocks(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_flags(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_gen(&self) -> u32; |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
impl MetadataExt for Metadata { |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat { |
|
||||||
unsafe { |
|
||||||
&*(self.as_inner().as_inner() as *const libc::stat |
|
||||||
as *const raw::stat) |
|
||||||
} |
|
||||||
} |
|
||||||
fn st_dev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_dev as u64 |
|
||||||
} |
|
||||||
fn st_ino(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_ino as u64 |
|
||||||
} |
|
||||||
fn st_mode(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_mode as u32 |
|
||||||
} |
|
||||||
fn st_nlink(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_nlink as u64 |
|
||||||
} |
|
||||||
fn st_uid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_uid as u32 |
|
||||||
} |
|
||||||
fn st_gid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_gid as u32 |
|
||||||
} |
|
||||||
fn st_rdev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_rdev as u64 |
|
||||||
} |
|
||||||
fn st_size(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_size as u64 |
|
||||||
} |
|
||||||
fn st_atime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime as i64 |
|
||||||
} |
|
||||||
fn st_atime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_mtime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime as i64 |
|
||||||
} |
|
||||||
fn st_mtime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_ctime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime as i64 |
|
||||||
} |
|
||||||
fn st_ctime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_birthtime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_birthtime as i64 |
|
||||||
} |
|
||||||
fn st_birthtime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_birthtime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_blksize(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blksize as u64 |
|
||||||
} |
|
||||||
fn st_blocks(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blocks as u64 |
|
||||||
} |
|
||||||
fn st_gen(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_gen as u32 |
|
||||||
} |
|
||||||
fn st_flags(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_flags as u32 |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
@ -1,16 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! OpenBSD-specific definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
pub mod raw; |
|
||||||
pub mod fs; |
|
@ -1,80 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! OpenBSD-specific raw type definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
#![rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "these type aliases are no longer supported by \ |
|
||||||
the standard library, the `libc` crate on \ |
|
||||||
crates.io should be used instead for the correct \ |
|
||||||
definitions")] |
|
||||||
#![allow(deprecated)] |
|
||||||
|
|
||||||
use os::raw::c_long; |
|
||||||
|
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type fflags_t = u32; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64; |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64; |
|
||||||
|
|
||||||
#[stable(feature = "pthread_t", since = "1.8.0")] |
|
||||||
pub type pthread_t = usize; |
|
||||||
|
|
||||||
#[repr(C)] |
|
||||||
#[derive(Clone)] |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub struct stat { |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mode: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_dev: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ino: u64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_nlink: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_uid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gid: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_rdev: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_atime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_mtime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_ctime_nsec: c_long, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_size: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blocks: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_blksize: i32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_flags: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_gen: u32, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_birthtime: i64, |
|
||||||
#[stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
pub st_birthtime_nsec: c_long, |
|
||||||
} |
|
@ -1,11 +0,0 @@ |
|||||||
Equivalent to C's `char` type. |
|
||||||
|
|
||||||
[C's `char` type] is completely unlike [Rust's `char` type]; while Rust's type represents a unicode scalar value, C's `char` type is just an ordinary integer. This type will always be either [`i8`] or [`u8`], as the type is defined as being one byte long. |
|
||||||
|
|
||||||
C chars are most commonly used to make C strings. Unlike Rust, where the length of a string is included alongside the string, C strings mark the end of a string with the character `'\0'`. See [`CStr`] for more information. |
|
||||||
|
|
||||||
[C's `char` type]: https://en.wikipedia.org/wiki/C_data_types#Basic_types |
|
||||||
[Rust's `char` type]: ../../primitive.char.html |
|
||||||
[`CStr`]: ../../ffi/struct.CStr.html |
|
||||||
[`i8`]: ../../primitive.i8.html |
|
||||||
[`u8`]: ../../primitive.u8.html |
|
@ -1,7 +0,0 @@ |
|||||||
Equivalent to C's `double` type. |
|
||||||
|
|
||||||
This type will almost always be [`f64`], which is guaranteed to be an [IEEE-754 double-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number with at least the precision of a [`float`], and it may be `f32` or something entirely different from the IEEE-754 standard. |
|
||||||
|
|
||||||
[IEEE-754 double-precision float]: https://en.wikipedia.org/wiki/IEEE_754 |
|
||||||
[`float`]: type.c_float.html |
|
||||||
[`f64`]: ../../primitive.f64.html |
|
@ -1,6 +0,0 @@ |
|||||||
Equivalent to C's `float` type. |
|
||||||
|
|
||||||
This type will almost always be [`f32`], which is guaranteed to be an [IEEE-754 single-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number, and it may have less precision than `f32` or not follow the IEEE-754 standard at all. |
|
||||||
|
|
||||||
[IEEE-754 single-precision float]: https://en.wikipedia.org/wiki/IEEE_754 |
|
||||||
[`f32`]: ../../primitive.f32.html |
|
@ -1,7 +0,0 @@ |
|||||||
Equivalent to C's `signed int` (`int`) type. |
|
||||||
|
|
||||||
This type will almost always be [`i32`], but may differ on some esoteric systems. The C standard technically only requires that this type be a signed integer that is at least the size of a [`short`]; some systems define it as an [`i16`], for example. |
|
||||||
|
|
||||||
[`short`]: type.c_short.html |
|
||||||
[`i32`]: ../../primitive.i32.html |
|
||||||
[`i16`]: ../../primitive.i16.html |
|
@ -1,7 +0,0 @@ |
|||||||
Equivalent to C's `signed long` (`long`) type. |
|
||||||
|
|
||||||
This type will always be [`i32`] or [`i64`]. Most notably, many Linux-based systems assume an `i64`, but Windows assumes `i32`. The C standard technically only requires that this type be a signed integer that is at least 32 bits and at least the size of an [`int`], although in practice, no system would have a `long` that is neither an `i32` nor `i64`. |
|
||||||
|
|
||||||
[`int`]: type.c_int.html |
|
||||||
[`i32`]: ../../primitive.i32.html |
|
||||||
[`i64`]: ../../primitive.i64.html |
|
@ -1,7 +0,0 @@ |
|||||||
Equivalent to C's `signed long long` (`long long`) type. |
|
||||||
|
|
||||||
This type will almost always be [`i64`], but may differ on some systems. The C standard technically only requires that this type be a signed integer that is at least 64 bits and at least the size of a [`long`], although in practice, no system would have a `long long` that is not an `i64`, as most systems do not have a standardised [`i128`] type. |
|
||||||
|
|
||||||
[`long`]: type.c_int.html |
|
||||||
[`i64`]: ../../primitive.i64.html |
|
||||||
[`i128`]: ../../primitive.i128.html |
|
@ -1,141 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Platform-specific types, as defined by C.
|
|
||||||
//!
|
|
||||||
//! Code that interacts via FFI will almost certainly be using the
|
|
||||||
//! base types provided by C, which aren't nearly as nicely defined
|
|
||||||
//! as Rust's primitive types. This module provides types which will
|
|
||||||
//! match those defined by C, so that code that interacts with C will
|
|
||||||
//! refer to the correct types.
|
|
||||||
|
|
||||||
#![stable(feature = "raw_os", since = "1.1.0")] |
|
||||||
|
|
||||||
use fmt; |
|
||||||
|
|
||||||
#[doc(include = "os/raw/char.md")] |
|
||||||
#[cfg(any(all(target_os = "linux", any(target_arch = "aarch64",
|
|
||||||
target_arch = "arm", |
|
||||||
target_arch = "powerpc", |
|
||||||
target_arch = "powerpc64", |
|
||||||
target_arch = "s390x")), |
|
||||||
all(target_os = "android", any(target_arch = "aarch64", |
|
||||||
target_arch = "arm")), |
|
||||||
all(target_os = "l4re", target_arch = "x86_64"), |
|
||||||
all(target_os = "netbsd", any(target_arch = "aarch64", |
|
||||||
target_arch = "arm", |
|
||||||
target_arch = "powerpc")), |
|
||||||
all(target_os = "openbsd", target_arch = "aarch64"), |
|
||||||
all(target_os = "fuchsia", target_arch = "aarch64")))] |
|
||||||
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = u8; |
|
||||||
#[doc(include = "os/raw/char.md")] |
|
||||||
#[cfg(not(any(all(target_os = "linux", any(target_arch = "aarch64",
|
|
||||||
target_arch = "arm", |
|
||||||
target_arch = "powerpc", |
|
||||||
target_arch = "powerpc64", |
|
||||||
target_arch = "s390x")), |
|
||||||
all(target_os = "android", any(target_arch = "aarch64", |
|
||||||
target_arch = "arm")), |
|
||||||
all(target_os = "l4re", target_arch = "x86_64"), |
|
||||||
all(target_os = "netbsd", any(target_arch = "aarch64", |
|
||||||
target_arch = "arm", |
|
||||||
target_arch = "powerpc")), |
|
||||||
all(target_os = "openbsd", target_arch = "aarch64"), |
|
||||||
all(target_os = "fuchsia", target_arch = "aarch64"))))] |
|
||||||
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = i8; |
|
||||||
#[doc(include = "os/raw/schar.md")] |
|
||||||
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_schar = i8; |
|
||||||
#[doc(include = "os/raw/uchar.md")] |
|
||||||
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_uchar = u8; |
|
||||||
#[doc(include = "os/raw/short.md")] |
|
||||||
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_short = i16; |
|
||||||
#[doc(include = "os/raw/ushort.md")] |
|
||||||
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_ushort = u16; |
|
||||||
#[doc(include = "os/raw/int.md")] |
|
||||||
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_int = i32; |
|
||||||
#[doc(include = "os/raw/uint.md")] |
|
||||||
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_uint = u32; |
|
||||||
#[doc(include = "os/raw/long.md")] |
|
||||||
#[cfg(any(target_pointer_width = "32", windows))] |
|
||||||
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_long = i32; |
|
||||||
#[doc(include = "os/raw/ulong.md")] |
|
||||||
#[cfg(any(target_pointer_width = "32", windows))] |
|
||||||
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulong = u32; |
|
||||||
#[doc(include = "os/raw/long.md")] |
|
||||||
#[cfg(all(target_pointer_width = "64", not(windows)))] |
|
||||||
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_long = i64; |
|
||||||
#[doc(include = "os/raw/ulong.md")] |
|
||||||
#[cfg(all(target_pointer_width = "64", not(windows)))] |
|
||||||
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulong = u64; |
|
||||||
#[doc(include = "os/raw/longlong.md")] |
|
||||||
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_longlong = i64; |
|
||||||
#[doc(include = "os/raw/ulonglong.md")] |
|
||||||
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulonglong = u64; |
|
||||||
#[doc(include = "os/raw/float.md")] |
|
||||||
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_float = f32; |
|
||||||
#[doc(include = "os/raw/double.md")] |
|
||||||
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_double = f64; |
|
||||||
|
|
||||||
/// Equivalent to C's `void` type when used as a [pointer].
|
|
||||||
///
|
|
||||||
/// In essence, `*const c_void` is equivalent to C's `const void*`
|
|
||||||
/// and `*mut c_void` is equivalent to C's `void*`. That said, this is
|
|
||||||
/// *not* the same as C's `void` return type, which is Rust's `()` type.
|
|
||||||
///
|
|
||||||
/// Ideally, this type would be equivalent to [`!`], but currently it may
|
|
||||||
/// be more ideal to use `c_void` for FFI purposes.
|
|
||||||
///
|
|
||||||
/// [`!`]: ../../primitive.never.html
|
|
||||||
/// [pointer]: ../../primitive.pointer.html
|
|
||||||
// NB: For LLVM to recognize the void pointer type and by extension
|
|
||||||
// functions like malloc(), we need to have it represented as i8* in
|
|
||||||
// LLVM bitcode. The enum used here ensures this and prevents misuse
|
|
||||||
// of the "raw" type by only having private variants.. We need two
|
|
||||||
// variants, because the compiler complains about the repr attribute
|
|
||||||
// otherwise.
|
|
||||||
#[repr(u8)] |
|
||||||
#[stable(feature = "raw_os", since = "1.1.0")] |
|
||||||
pub enum c_void { |
|
||||||
#[unstable(feature = "c_void_variant", reason = "should not have to exist",
|
|
||||||
issue = "0")] |
|
||||||
#[doc(hidden)] __variant1, |
|
||||||
#[unstable(feature = "c_void_variant", reason = "should not have to exist",
|
|
||||||
issue = "0")] |
|
||||||
#[doc(hidden)] __variant2, |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "std_debug", since = "1.16.0")] |
|
||||||
impl fmt::Debug for c_void { |
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
|
||||||
f.pad("c_void") |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
#[cfg(test)] |
|
||||||
#[allow(unused_imports)] |
|
||||||
mod tests { |
|
||||||
use any::TypeId; |
|
||||||
use libc; |
|
||||||
use mem; |
|
||||||
|
|
||||||
macro_rules! ok { |
|
||||||
($($t:ident)*) => {$( |
|
||||||
assert!(TypeId::of::<libc::$t>() == TypeId::of::<raw::$t>(), |
|
||||||
"{} is wrong", stringify!($t)); |
|
||||||
)*} |
|
||||||
} |
|
||||||
|
|
||||||
#[test] |
|
||||||
fn same() { |
|
||||||
use os::raw; |
|
||||||
ok!(c_char c_schar c_uchar c_short c_ushort c_int c_uint c_long c_ulong |
|
||||||
c_longlong c_ulonglong c_float c_double); |
|
||||||
} |
|
||||||
} |
|
@ -1,6 +0,0 @@ |
|||||||
Equivalent to C's `signed char` type. |
|
||||||
|
|
||||||
This type will always be [`i8`], but is included for completeness. It is defined as being a signed integer the same size as a C [`char`]. |
|
||||||
|
|
||||||
[`char`]: type.c_char.html |
|
||||||
[`i8`]: ../../primitive.i8.html |
|
@ -1,6 +0,0 @@ |
|||||||
Equivalent to C's `signed short` (`short`) type. |
|
||||||
|
|
||||||
This type will almost always be [`i16`], but may differ on some esoteric systems. The C standard technically only requires that this type be a signed integer with at least 16 bits; some systems may define it as `i32`, for example. |
|
||||||
|
|
||||||
[`char`]: type.c_char.html |
|
||||||
[`i16`]: ../../primitive.i16.html |
|
@ -1,6 +0,0 @@ |
|||||||
Equivalent to C's `unsigned char` type. |
|
||||||
|
|
||||||
This type will always be [`u8`], but is included for completeness. It is defined as being an unsigned integer the same size as a C [`char`]. |
|
||||||
|
|
||||||
[`char`]: type.c_char.html |
|
||||||
[`u8`]: ../../primitive.u8.html |
|
@ -1,7 +0,0 @@ |
|||||||
Equivalent to C's `unsigned int` type. |
|
||||||
|
|
||||||
This type will almost always be [`u32`], but may differ on some esoteric systems. The C standard technically only requires that this type be an unsigned integer with the same size as an [`int`]; some systems define it as a [`u16`], for example. |
|
||||||
|
|
||||||
[`int`]: type.c_int.html |
|
||||||
[`u32`]: ../../primitive.u32.html |
|
||||||
[`u16`]: ../../primitive.u16.html |
|
@ -1,7 +0,0 @@ |
|||||||
Equivalent to C's `unsigned long` type. |
|
||||||
|
|
||||||
This type will always be [`u32`] or [`u64`]. Most notably, many Linux-based systems assume an `u64`, but Windows assumes `u32`. The C standard technically only requires that this type be an unsigned integer with the size of a [`long`], although in practice, no system would have a `ulong` that is neither a `u32` nor `u64`. |
|
||||||
|
|
||||||
[`long`]: type.c_long.html |
|
||||||
[`u32`]: ../../primitive.u32.html |
|
||||||
[`u64`]: ../../primitive.u64.html |
|
@ -1,7 +0,0 @@ |
|||||||
Equivalent to C's `unsigned long long` type. |
|
||||||
|
|
||||||
This type will almost always be [`u64`], but may differ on some systems. The C standard technically only requires that this type be an unsigned integer with the size of a [`long long`], although in practice, no system would have a `long long` that is not a `u64`, as most systems do not have a standardised [`u128`] type. |
|
||||||
|
|
||||||
[`long long`]: type.c_longlong.html |
|
||||||
[`u64`]: ../../primitive.u64.html |
|
||||||
[`u128`]: ../../primitive.u128.html |
|
@ -1,6 +0,0 @@ |
|||||||
Equivalent to C's `unsigned short` type. |
|
||||||
|
|
||||||
This type will almost always be [`u16`], but may differ on some esoteric systems. The C standard technically only requires that this type be an unsigned integer with the same size as a [`short`]. |
|
||||||
|
|
||||||
[`short`]: type.c_short.html |
|
||||||
[`u16`]: ../../primitive.u16.html |
|
@ -1,130 +0,0 @@ |
|||||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
#![stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
use libc; |
|
||||||
|
|
||||||
use fs::Metadata; |
|
||||||
use sys_common::AsInner; |
|
||||||
|
|
||||||
#[allow(deprecated)] |
|
||||||
use os::solaris::raw; |
|
||||||
|
|
||||||
/// OS-specific extensions to [`fs::Metadata`].
|
|
||||||
///
|
|
||||||
/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
pub trait MetadataExt { |
|
||||||
/// Gain a reference to the underlying `stat` structure which contains
|
|
||||||
/// the raw information returned by the OS.
|
|
||||||
///
|
|
||||||
/// The contents of the returned `stat` are **not** consistent across
|
|
||||||
/// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
|
|
||||||
/// cross-Unix abstractions contained within the raw stat.
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
#[rustc_deprecated(since = "1.8.0",
|
|
||||||
reason = "deprecated in favor of the accessor \ |
|
||||||
methods of this trait")] |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat; |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_dev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ino(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mode(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_nlink(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_uid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_gid(&self) -> u32; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_rdev(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_size(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_atime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_mtime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_ctime_nsec(&self) -> i64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blksize(&self) -> u64; |
|
||||||
#[stable(feature = "metadata_ext2", since = "1.8.0")] |
|
||||||
fn st_blocks(&self) -> u64; |
|
||||||
} |
|
||||||
|
|
||||||
#[stable(feature = "metadata_ext", since = "1.1.0")] |
|
||||||
impl MetadataExt for Metadata { |
|
||||||
#[allow(deprecated)] |
|
||||||
fn as_raw_stat(&self) -> &raw::stat { |
|
||||||
unsafe { |
|
||||||
&*(self.as_inner().as_inner() as *const libc::stat |
|
||||||
as *const raw::stat) |
|
||||||
} |
|
||||||
} |
|
||||||
fn st_dev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_dev as u64 |
|
||||||
} |
|
||||||
fn st_ino(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_ino as u64 |
|
||||||
} |
|
||||||
fn st_mode(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_mode as u32 |
|
||||||
} |
|
||||||
fn st_nlink(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_nlink as u64 |
|
||||||
} |
|
||||||
fn st_uid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_uid as u32 |
|
||||||
} |
|
||||||
fn st_gid(&self) -> u32 { |
|
||||||
self.as_inner().as_inner().st_gid as u32 |
|
||||||
} |
|
||||||
fn st_rdev(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_rdev as u64 |
|
||||||
} |
|
||||||
fn st_size(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_size as u64 |
|
||||||
} |
|
||||||
fn st_atime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime as i64 |
|
||||||
} |
|
||||||
fn st_atime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_atime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_mtime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime as i64 |
|
||||||
} |
|
||||||
fn st_mtime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_mtime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_ctime(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime as i64 |
|
||||||
} |
|
||||||
fn st_ctime_nsec(&self) -> i64 { |
|
||||||
self.as_inner().as_inner().st_ctime_nsec as i64 |
|
||||||
} |
|
||||||
fn st_blksize(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blksize as u64 |
|
||||||
} |
|
||||||
fn st_blocks(&self) -> u64 { |
|
||||||
self.as_inner().as_inner().st_blocks as u64 |
|
||||||
} |
|
||||||
} |
|
@ -1,16 +0,0 @@ |
|||||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
|
||||||
// file at the top-level directory of this distribution and at
|
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
||||||
// option. This file may not be copied, modified, or distributed
|
|
||||||
// except according to those terms.
|
|
||||||
|
|
||||||
//! Solaris-specific definitions
|
|
||||||
|
|
||||||
#![stable(feature = "raw_ext", since = "1.1.0")] |
|
||||||
|
|
||||||
pub mod raw; |
|
||||||
pub mod fs; |
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue