<commit_before>//! This module contains paths to types and functions Clippy needs to know
//! about.
//!
//! Whenever possible, please consider diagnostic items over hardcoded paths.
//! See <https://github.com/rust-lang/rust-clippy/issues/5393> for more information.

pub const ANY_TRAIT: [&str; 3] = ["std", "any", "Any"];
pub const ARC_PTR_EQ: [&str; 4] = ["alloc", "sync", "Arc", "ptr_eq"];
pub const ASMUT_TRAIT: [&str; 3] = ["core", "convert", "AsMut"];
pub const ASREF_TRAIT: [&str; 3] = ["core", "convert", "AsRef"];
pub const BEGIN_PANIC: [&str; 3] = ["std", "panicking", "begin_panic"];
pub const BEGIN_PANIC_FMT: [&str; 3] = ["std", "panicking", "begin_panic_fmt"];
pub const BINARY_HEAP: [&str; 4] = ["alloc", "collections", "binary_heap", "BinaryHeap"];
pub const BORROW_TRAIT: [&str; 3] = ["core", "borrow", "Borrow"];
pub const BOX: [&str; 3] = ["alloc", "boxed", "Box"];
pub const BTREEMAP: [&str; 5] = ["alloc", "collections", "btree", "map", "BTreeMap"];
pub const BTREEMAP_ENTRY: [&str; 6] = ["alloc", "collections", "btree", "map", "entry", "Entry"];
pub const BTREESET: [&str; 5] = ["alloc", "collections", "btree", "set", "BTreeSet"];
pub const CLONE_TRAIT: [&str; 3] = ["core", "clone", "Clone"];
pub const CLONE_TRAIT_METHOD: [&str; 4] = ["core", "clone", "Clone", "clone"];
pub const CMP_MAX: [&str; 3] = ["core", "cmp", "max"];
pub const CMP_MIN: [&str; 3] = ["core", "cmp", "min"];
pub const COW: [&str; 3] = ["alloc", "borrow", "Cow"];
pub const CSTRING_AS_C_STR: [&str; 5] = ["std", "ffi", "c_str", "CString", "as_c_str"];
pub const DEFAULT_TRAIT: [&str; 3] = ["core", "default", "Default"];
pub const DEFAULT_TRAIT_METHOD: [&str; 4] = ["core", "default", "Default", "default"];
pub const DEREF_MUT_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "DerefMut", "deref_mut"];
pub const DEREF_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "Deref", "deref"];
pub const DISPLAY_FMT_METHOD: [&str; 4] = ["core", "fmt", "Display", "fmt"];
pub const DISPLAY_TRAIT: [&str; 3] = ["core", "fmt", "Display"];
pub const DOUBLE_ENDED_ITERATOR: [&str; 4] = ["core", "iter", "traits", "DoubleEndedIterator"];
pub const DROP: [&str; 3] = ["core", "mem", "drop"];
pub const DURATION: [&str; 3] = ["core", "time", "Duration"];
pub const EARLY_CONTEXT: [&str; 2] = ["rustc_lint", "EarlyContext"];
pub const EXIT: [&str; 3] = ["std", "process", "exit"];
pub const F32_EPSILON: [&str; 4] = ["core", "f32", "<impl f32>", "EPSILON"];
pub const F64_EPSILON: [&str; 4] = ["core", "f64", "<impl f64>", "EPSILON"];
pub const FILE: [&str; 3] = ["std", "fs", "File"];
pub const FILE_TYPE: [&str; 3] = ["std", "fs", "FileType"];
pub const FMT_ARGUMENTS_NEW_V1: [&str; 4] = ["core", "fmt", "Arguments", "new_v1"];
pub const FMT_ARGUMENTS_NEW_V1_FORMATTED: [&str; 4] = ["core", "fmt", "Arguments", "new_v1_formatted"];
pub const FMT_ARGUMENTV1_NEW: [&str; 4] = ["core", "fmt", "ArgumentV1", "new"];
pub const FN: [&str; 3] = ["core", "ops", "Fn"];
pub const FN_MUT: [&str; 3] = ["core", "ops", "FnMut"];
pub const FN_ONCE: [&str; 3] = ["core", "ops", "FnOnce"];
pub const FROM_FROM: [&str; 4] = ["core", "convert", "From", "from"];
pub const FROM_TRAIT: [&str; 3] = ["core", "convert", "From"];
pub const FUTURE_FROM_GENERATOR: [&str; 3] = ["core", "future", "from_generator"];
pub const HASH: [&str; 3] = ["core", "hash", "Hash"];
pub const HASHMAP: [&str; 5] = ["std", "collections", "hash", "map", "HashMap"];
pub const HASHMAP_ENTRY: [&str; 5] = ["std", "collections", "hash", "map", "Entry"];
pub const HASHSET: [&str; 5] = ["std", "collections", "hash", "set", "HashSet"];
pub const INDEX: [&str; 3] = ["core", "ops", "Index"];
pub const INDEX_MUT: [&str; 3] = ["core", "ops", "IndexMut"];
pub const INTO: [&str; 3] = ["core", "convert", "Into"];
pub const INTO_ITERATOR: [&str; 5] = ["core", "iter", "traits", "collect", "IntoIterator"];
pub const IO_READ: [&str; 3] = ["std", "io", "Read"];
pub const IO_WRITE: [&str; 3] = ["std", "io", "Write"];
pub const ITERATOR: [&str; 5] = ["core", "iter", "traits", "iterator", "Iterator"];
pub const LATE_CONTEXT: [&str; 2] = ["rustc_lint", "LateContext"];
pub const LINKED_LIST: [&str; 4] = ["alloc", "collections", "linked_list", "LinkedList"];
pub const LINT: [&str; 3] = ["rustc_session", "lint", "Lint"];
pub const MEM_DISCRIMINANT: [&str; 3] = ["core", "mem", "discriminant"];
pub const MEM_FORGET: [&str; 3] = ["core", "mem", "forget"];
pub const MEM_MANUALLY_DROP: [&str; 4] = ["core", "mem", "manually_drop", "ManuallyDrop"];
pub const MEM_MAYBEUNINIT: [&str; 4] = ["core", "mem", "maybe_uninit", "MaybeUninit"];
pub const MEM_MAYBEUNINIT_UNINIT: [&str; 5] = ["core", "mem", "maybe_uninit", "MaybeUninit", "uninit"];
pub const MEM_REPLACE: [&str; 3] = ["core", "mem", "replace"];
pub const MUTEX_GUARD: [&str; 4] = ["std", "sync", "mutex", "MutexGuard"];
pub const OPEN_OPTIONS: [&str; 3] = ["std", "fs", "OpenOptions"];
pub const OPS_MODULE: [&str; 2] = ["core", "ops"];
pub const OPTION: [&str; 3] = ["core", "option", "Option"];
pub const OPTION_NONE: [&str; 4] = ["core", "option", "Option", "None"];
pub const OPTION_SOME: [&str; 4] = ["core", "option", "Option", "Some"];
pub const ORD: [&str; 3] = ["core", "cmp", "Ord"];
pub const OS_STRING: [&str; 4] = ["std", "ffi", "os_str", "OsString"];
pub const OS_STRING_AS_OS_STR: [&str; 5] = ["std", "ffi", "os_str", "OsString", "as_os_str"];
pub const OS_STR_TO_OS_STRING: [&str; 5] = ["std", "ffi", "os_str", "OsStr", "to_os_string"];
pub const PARKING_LOT_MUTEX_GUARD: [&str; 2] = ["parking_lot", "MutexGuard"];
pub const PARKING_LOT_RWLOCK_READ_GUARD: [&str; 2] = ["parking_lot", "RwLockReadGuard"];
pub const PARKING_LOT_RWLOCK_WRITE_GUARD: [&str; 2] = ["parking_lot", "RwLockWriteGuard"];
pub const PATH: [&str; 3] = ["std", "path", "Path"];
pub const PATH_BUF: [&str; 3] = ["std", "path", "PathBuf"];
pub const PATH_BUF_AS_PATH: [&str; 4] = ["std", "path", "PathBuf", "as_path"];
pub const PATH_TO_PATH_BUF: [&str; 4] = ["std", "path", "Path", "to_path_buf"];
pub const POLL: [&str; 4] = ["core", "task", "poll", "Poll"];
pub const PTR_EQ: [&str; 3] = ["core", "ptr", "eq"];
pub const PTR_NULL: [&str; 3] = ["core", "ptr", "null"];
pub const PTR_NULL_MUT: [&str; 3] = ["core", "ptr", "null_mut"];
pub const PUSH_STR: [&str; 4] = ["alloc", "string", "String", "push_str"];
pub const RANGE_ARGUMENT_TRAIT: [&str; 3] = ["core", "ops", "RangeBounds"];
pub const RC: [&str; 3] = ["alloc", "rc", "Rc"];
pub const RC_PTR_EQ: [&str; 4] = ["alloc", "rc", "Rc", "ptr_eq"];
pub const RECEIVER: [&str; 4] = ["std", "sync", "mpsc", "Receiver"];
pub const REFCELL_REF: [&str; 3] = ["core", "cell", "Ref"];
pub const REFCELL_REFMUT: [&str; 3] = ["core", "cell", "RefMut"];
pub const REGEX_BUILDER_NEW: [&str; 5] = ["regex", "re_builder", "unicode", "RegexBuilder", "new"];
pub const REGEX_BYTES_BUILDER_NEW: [&str; 5] = ["regex", "re_builder", "bytes", "RegexBuilder", "new"];
pub const REGEX_BYTES_NEW: [&str; 4] = ["regex", "re_bytes", "Regex", "new"];
pub const REGEX_BYTES_SET_NEW: [&str; 5] = ["regex", "re_set", "bytes", "RegexSet", "new"];
pub const REGEX_NEW: [&str; 4] = ["regex", "re_unicode", "Regex", "new"];
pub const REGEX_SET_NEW: [&str; 5] = ["regex", "re_set", "unicode", "RegexSet", "new"];
pub const REPEAT: [&str; 3] = ["core", "iter", "repeat"];
pub const RESULT: [&str; 3] = ["core", "result", "Result"];
pub const RESULT_ERR: [&str; 4] = ["core", "result", "Result", "Err"];
pub const RESULT_OK: [&str; 4] = ["core", "result", "Result", "Ok"];
pub const RWLOCK_READ_GUARD: [&str; 4] = ["std", "sync", "rwlock", "RwLockReadGuard"];
pub const RWLOCK_WRITE_GUARD: [&str; 4] = ["std", "sync", "rwlock", "RwLockWriteGuard"];
pub const SERDE_DESERIALIZE: [&str; 3] = ["serde", "de", "Deserialize"];
pub const SERDE_DE_VISITOR: [&str; 3] = ["serde", "de", "Visitor"];
pub const SLICE_INTO_VEC: [&str; 4] = ["alloc", "slice", "<impl [T]>", "into_vec"];
pub const SLICE_ITER: [&str; 4] = ["core", "slice", "iter", "Iter"];
pub const STDERR: [&str; 4] = ["std", "io", "stdio", "stderr"];
pub const STDOUT: [&str; 4] = ["std", "io", "stdio", "stdout"];
pub const STD_CONVERT_IDENTITY: [&str; 3] = ["std", "convert", "identity"];
pub const STD_FS_CREATE_DIR: [&str; 3] = ["std", "fs", "create_dir"];
pub const STD_MEM_TRANSMUTE: [&str; 3] = ["std", "mem", "transmute"];
pub const STD_PTR_NULL: [&str; 3] = ["std", "ptr", "null"];
pub const STRING: [&str; 3] = ["alloc", "string", "String"];
pub const STRING_AS_MUT_STR: [&str; 4] = ["alloc", "string", "String", "as_mut_str"];
pub const STRING_AS_STR: [&str; 4] = ["alloc", "string", "String", "as_str"];
pub const STR_ENDS_WITH: [&str; 4] = ["core", "str", "<impl str>", "ends_with"];
pub const STR_LEN: [&str; 4] = ["core", "str", "<impl str>", "len"];
pub const STR_STARTS_WITH: [&str; 4] = ["core", "str", "<impl str>", "starts_with"];
pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"];
pub const TO_OWNED: [&str; 3] = ["alloc", "borrow", "ToOwned"];
pub const TO_OWNED_METHOD: [&str; 4] = ["alloc", "borrow", "ToOwned", "to_owned"];
pub const TO_STRING: [&str; 3] = ["alloc", "string", "ToString"];
pub const TO_STRING_METHOD: [&str; 4] = ["alloc", "string", "ToString", "to_string"];
pub const TRANSMUTE: [&str; 4] = ["core", "intrinsics", "", "transmute"];
pub const TRY_FROM: [&str; 4] = ["core", "convert", "TryFrom", "try_from"];
pub const TRY_INTO_TRAIT: [&str; 3] = ["core", "convert", "TryInto"];
pub const VEC: [&str; 3] = ["alloc", "vec", "Vec"];
pub const VEC_AS_MUT_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_mut_slice"];
pub const VEC_AS_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_slice"];
pub const VEC_DEQUE: [&str; 4] = ["alloc", "collections", "vec_deque", "VecDeque"];
pub const VEC_FROM_ELEM: [&str; 3] = ["alloc", "vec", "from_elem"];
pub const VEC_NEW: [&str; 4] = ["alloc", "vec", "Vec", "new"];
pub const VEC_RESIZE: [&str; 4] = ["alloc", "vec", "Vec", "resize"];
pub const WEAK_ARC: [&str; 3] = ["alloc", "sync", "Weak"];
pub const WEAK_RC: [&str; 3] = ["alloc", "rc", "Weak"];
<commit_msg>Auto merge of #6282 - giraffate:sync-from-rust, r=ebroto<commit_after>//! This module contains paths to types and functions Clippy needs to know
//! about.
//!
//! Whenever possible, please consider diagnostic items over hardcoded paths.
//! See <https://github.com/rust-lang/rust-clippy/issues/5393> for more information.

pub const ANY_TRAIT: [&str; 3] = ["std", "any", "Any"];
pub const ARC_PTR_EQ: [&str; 4] = ["alloc", "sync", "Arc", "ptr_eq"];
pub const ASMUT_TRAIT: [&str; 3] = ["core", "convert", "AsMut"];
pub const ASREF_TRAIT: [&str; 3] = ["core", "convert", "AsRef"];
pub const BEGIN_PANIC: [&str; 3] = ["std", "panicking", "begin_panic"];
pub const BEGIN_PANIC_FMT: [&str; 3] = ["std", "panicking", "begin_panic_fmt"];
pub const BINARY_HEAP: [&str; 4] = ["alloc", "collections", "binary_heap", "BinaryHeap"];
pub const BORROW_TRAIT: [&str; 3] = ["core", "borrow", "Borrow"];
pub const BOX: [&str; 3] = ["alloc", "boxed", "Box"];
pub const BTREEMAP: [&str; 5] = ["alloc", "collections", "btree", "map", "BTreeMap"];
pub const BTREEMAP_ENTRY: [&str; 6] = ["alloc", "collections", "btree", "map", "entry", "Entry"];
pub const BTREESET: [&str; 5] = ["alloc", "collections", "btree", "set", "BTreeSet"];
pub const CLONE_TRAIT: [&str; 3] = ["core", "clone", "Clone"];
pub const CLONE_TRAIT_METHOD: [&str; 4] = ["core", "clone", "Clone", "clone"];
pub const CMP_MAX: [&str; 3] = ["core", "cmp", "max"];
pub const CMP_MIN: [&str; 3] = ["core", "cmp", "min"];
pub const COW: [&str; 3] = ["alloc", "borrow", "Cow"];
pub const CSTRING_AS_C_STR: [&str; 5] = ["std", "ffi", "c_str", "CString", "as_c_str"];
pub const DEFAULT_TRAIT: [&str; 3] = ["core", "default", "Default"];
pub const DEFAULT_TRAIT_METHOD: [&str; 4] = ["core", "default", "Default", "default"];
pub const DEREF_MUT_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "DerefMut", "deref_mut"];
pub const DEREF_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "Deref", "deref"];
pub const DISPLAY_FMT_METHOD: [&str; 4] = ["core", "fmt", "Display", "fmt"];
pub const DISPLAY_TRAIT: [&str; 3] = ["core", "fmt", "Display"];
pub const DOUBLE_ENDED_ITERATOR: [&str; 4] = ["core", "iter", "traits", "DoubleEndedIterator"];
pub const DROP: [&str; 3] = ["core", "mem", "drop"];
pub const DURATION: [&str; 3] = ["core", "time", "Duration"];
pub const EARLY_CONTEXT: [&str; 2] = ["rustc_lint", "EarlyContext"];
pub const EXIT: [&str; 3] = ["std", "process", "exit"];
pub const F32_EPSILON: [&str; 4] = ["core", "f32", "<impl f32>", "EPSILON"];
pub const F64_EPSILON: [&str; 4] = ["core", "f64", "<impl f64>", "EPSILON"];
pub const FILE: [&str; 3] = ["std", "fs", "File"];
pub const FILE_TYPE: [&str; 3] = ["std", "fs", "FileType"];
pub const FMT_ARGUMENTS_NEW_V1: [&str; 4] = ["core", "fmt", "Arguments", "new_v1"];
pub const FMT_ARGUMENTS_NEW_V1_FORMATTED: [&str; 4] = ["core", "fmt", "Arguments", "new_v1_formatted"];
pub const FMT_ARGUMENTV1_NEW: [&str; 4] = ["core", "fmt", "ArgumentV1", "new"];
pub const FN: [&str; 3] = ["core", "ops", "Fn"];
pub const FN_MUT: [&str; 3] = ["core", "ops", "FnMut"];
pub const FN_ONCE: [&str; 3] = ["core", "ops", "FnOnce"];
pub const FROM_FROM: [&str; 4] = ["core", "convert", "From", "from"];
pub const FROM_TRAIT: [&str; 3] = ["core", "convert", "From"];
pub const FUTURE_FROM_GENERATOR: [&str; 3] = ["core", "future", "from_generator"];
pub const HASH: [&str; 3] = ["core", "hash", "Hash"];
pub const HASHMAP: [&str; 5] = ["std", "collections", "hash", "map", "HashMap"];
pub const HASHMAP_ENTRY: [&str; 5] = ["std", "collections", "hash", "map", "Entry"];
pub const HASHSET: [&str; 5] = ["std", "collections", "hash", "set", "HashSet"];
pub const INDEX: [&str; 3] = ["core", "ops", "Index"];
pub const INDEX_MUT: [&str; 3] = ["core", "ops", "IndexMut"];
pub const INTO: [&str; 3] = ["core", "convert", "Into"];
pub const INTO_ITERATOR: [&str; 5] = ["core", "iter", "traits", "collect", "IntoIterator"];
pub const IO_READ: [&str; 3] = ["std", "io", "Read"];
pub const IO_WRITE: [&str; 3] = ["std", "io", "Write"];
pub const ITERATOR: [&str; 5] = ["core", "iter", "traits", "iterator", "Iterator"];
pub const LATE_CONTEXT: [&str; 2] = ["rustc_lint", "LateContext"];
pub const LINKED_LIST: [&str; 4] = ["alloc", "collections", "linked_list", "LinkedList"];
pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"];
pub const MEM_DISCRIMINANT: [&str; 3] = ["core", "mem", "discriminant"];
pub const MEM_FORGET: [&str; 3] = ["core", "mem", "forget"];
pub const MEM_MANUALLY_DROP: [&str; 4] = ["core", "mem", "manually_drop", "ManuallyDrop"];
pub const MEM_MAYBEUNINIT: [&str; 4] = ["core", "mem", "maybe_uninit", "MaybeUninit"];
pub const MEM_MAYBEUNINIT_UNINIT: [&str; 5] = ["core", "mem", "maybe_uninit", "MaybeUninit", "uninit"];
pub const MEM_REPLACE: [&str; 3] = ["core", "mem", "replace"];
pub const MUTEX_GUARD: [&str; 4] = ["std", "sync", "mutex", "MutexGuard"];
pub const OPEN_OPTIONS: [&str; 3] = ["std", "fs", "OpenOptions"];
pub const OPS_MODULE: [&str; 2] = ["core", "ops"];
pub const OPTION: [&str; 3] = ["core", "option", "Option"];
pub const OPTION_NONE: [&str; 4] = ["core", "option", "Option", "None"];
pub const OPTION_SOME: [&str; 4] = ["core", "option", "Option", "Some"];
pub const ORD: [&str; 3] = ["core", "cmp", "Ord"];
pub const OS_STRING: [&str; 4] = ["std", "ffi", "os_str", "OsString"];
pub const OS_STRING_AS_OS_STR: [&str; 5] = ["std", "ffi", "os_str", "OsString", "as_os_str"];
pub const OS_STR_TO_OS_STRING: [&str; 5] = ["std", "ffi", "os_str", "OsStr", "to_os_string"];
pub const PARKING_LOT_MUTEX_GUARD: [&str; 2] = ["parking_lot", "MutexGuard"];
pub const PARKING_LOT_RWLOCK_READ_GUARD: [&str; 2] = ["parking_lot", "RwLockReadGuard"];
pub const PARKING_LOT_RWLOCK_WRITE_GUARD: [&str; 2] = ["parking_lot", "RwLockWriteGuard"];
pub const PATH: [&str; 3] = ["std", "path", "Path"];
pub const PATH_BUF: [&str; 3] = ["std", "path", "PathBuf"];
pub const PATH_BUF_AS_PATH: [&str; 4] = ["std", "path", "PathBuf", "as_path"];
pub const PATH_TO_PATH_BUF: [&str; 4] = ["std", "path", "Path", "to_path_buf"];
pub const POLL: [&str; 4] = ["core", "task", "poll", "Poll"];
pub const PTR_EQ: [&str; 3] = ["core", "ptr", "eq"];
pub const PTR_NULL: [&str; 3] = ["core", "ptr", "null"];
pub const PTR_NULL_MUT: [&str; 3] = ["core", "ptr", "null_mut"];
pub const PUSH_STR: [&str; 4] = ["alloc", "string", "String", "push_str"];
pub const RANGE_ARGUMENT_TRAIT: [&str; 3] = ["core", "ops", "RangeBounds"];
pub const RC: [&str; 3] = ["alloc", "rc", "Rc"];
pub const RC_PTR_EQ: [&str; 4] = ["alloc", "rc", "Rc", "ptr_eq"];
pub const RECEIVER: [&str; 4] = ["std", "sync", "mpsc", "Receiver"];
pub const REFCELL_REF: [&str; 3] = ["core", "cell", "Ref"];
pub const REFCELL_REFMUT: [&str; 3] = ["core", "cell", "RefMut"];
pub const REGEX_BUILDER_NEW: [&str; 5] = ["regex", "re_builder", "unicode", "RegexBuilder", "new"];
pub const REGEX_BYTES_BUILDER_NEW: [&str; 5] = ["regex", "re_builder", "bytes", "RegexBuilder", "new"];
pub const REGEX_BYTES_NEW: [&str; 4] = ["regex", "re_bytes", "Regex", "new"];
pub const REGEX_BYTES_SET_NEW: [&str; 5] = ["regex", "re_set", "bytes", "RegexSet", "new"];
pub const REGEX_NEW: [&str; 4] = ["regex", "re_unicode", "Regex", "new"];
pub const REGEX_SET_NEW: [&str; 5] = ["regex", "re_set", "unicode", "RegexSet", "new"];
pub const REPEAT: [&str; 3] = ["core", "iter", "repeat"];
pub const RESULT: [&str; 3] = ["core", "result", "Result"];
pub const RESULT_ERR: [&str; 4] = ["core", "result", "Result", "Err"];
pub const RESULT_OK: [&str; 4] = ["core", "result", "Result", "Ok"];
pub const RWLOCK_READ_GUARD: [&str; 4] = ["std", "sync", "rwlock", "RwLockReadGuard"];
pub const RWLOCK_WRITE_GUARD: [&str; 4] = ["std", "sync", "rwlock", "RwLockWriteGuard"];
pub const SERDE_DESERIALIZE: [&str; 3] = ["serde", "de", "Deserialize"];
pub const SERDE_DE_VISITOR: [&str; 3] = ["serde", "de", "Visitor"];
pub const SLICE_INTO_VEC: [&str; 4] = ["alloc", "slice", "<impl [T]>", "into_vec"];
pub const SLICE_ITER: [&str; 4] = ["core", "slice", "iter", "Iter"];
pub const STDERR: [&str; 4] = ["std", "io", "stdio", "stderr"];
pub const STDOUT: [&str; 4] = ["std", "io", "stdio", "stdout"];
pub const STD_CONVERT_IDENTITY: [&str; 3] = ["std", "convert", "identity"];
pub const STD_FS_CREATE_DIR: [&str; 3] = ["std", "fs", "create_dir"];
pub const STD_MEM_TRANSMUTE: [&str; 3] = ["std", "mem", "transmute"];
pub const STD_PTR_NULL: [&str; 3] = ["std", "ptr", "null"];
pub const STRING: [&str; 3] = ["alloc", "string", "String"];
pub const STRING_AS_MUT_STR: [&str; 4] = ["alloc", "string", "String", "as_mut_str"];
pub const STRING_AS_STR: [&str; 4] = ["alloc", "string", "String", "as_str"];
pub const STR_ENDS_WITH: [&str; 4] = ["core", "str", "<impl str>", "ends_with"];
pub const STR_LEN: [&str; 4] = ["core", "str", "<impl str>", "len"];
pub const STR_STARTS_WITH: [&str; 4] = ["core", "str", "<impl str>", "starts_with"];
pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"];
pub const TO_OWNED: [&str; 3] = ["alloc", "borrow", "ToOwned"];
pub const TO_OWNED_METHOD: [&str; 4] = ["alloc", "borrow", "ToOwned", "to_owned"];
pub const TO_STRING: [&str; 3] = ["alloc", "string", "ToString"];
pub const TO_STRING_METHOD: [&str; 4] = ["alloc", "string", "ToString", "to_string"];
pub const TRANSMUTE: [&str; 4] = ["core", "intrinsics", "", "transmute"];
pub const TRY_FROM: [&str; 4] = ["core", "convert", "TryFrom", "try_from"];
pub const TRY_INTO_TRAIT: [&str; 3] = ["core", "convert", "TryInto"];
pub const VEC: [&str; 3] = ["alloc", "vec", "Vec"];
pub const VEC_AS_MUT_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_mut_slice"];
pub const VEC_AS_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_slice"];
pub const VEC_DEQUE: [&str; 4] = ["alloc", "collections", "vec_deque", "VecDeque"];
pub const VEC_FROM_ELEM: [&str; 3] = ["alloc", "vec", "from_elem"];
pub const VEC_NEW: [&str; 4] = ["alloc", "vec", "Vec", "new"];
pub const VEC_RESIZE: [&str; 4] = ["alloc", "vec", "Vec", "resize"];
pub const WEAK_ARC: [&str; 3] = ["alloc", "sync", "Weak"];
pub const WEAK_RC: [&str; 3] = ["alloc", "rc", "Weak"];
<|endoftext|>


<commit_before>//! Source file support for diagnostic reporting.

use std::ops::Range;

/// A line within a source file.
pub struct Line<Source> {
    /// The starting byte index of the line.
    pub start: usize,
    /// The line number.
    pub number: usize,
    /// The source of the line.
    pub source: Source,
}

impl<Source> Line<Source>
where
    Source: AsRef<str>,
{
    /// The column index at the given byte index in the source file.
    /// This is the number of characters to the given byte index.
    ///
    /// If the byte index is smaller than the start of the line, then `0` is returned.
    /// If the byte index is past the end of the line, the column index of the last
    /// character `+ 1` is returned.
    ///
    /// # Example
    ///
    /// ```rust
    /// use codespan_reporting::files::Line;
    ///
    /// let line = Line {
    ///     start: 2,
    ///     number: 2,
    ///     source: "🗻∈🌏",
    /// };
    ///
    /// assert_eq!(line.column_index(0), 0);
    /// assert_eq!(line.column_index(line.start + 0), 0);
    /// assert_eq!(line.column_index(line.start + 1), 0);
    /// assert_eq!(line.column_index(line.start + 4), 1);
    /// assert_eq!(line.column_index(line.start + 8), 2);
    /// assert_eq!(line.column_index(line.start + line.source.len()), 3);
    /// ```
    pub fn column_index(&self, byte_index: usize) -> usize {
        match byte_index.checked_sub(self.start) {
            None => 0,
            Some(relative_index) => {
                let line_source = self.source.as_ref();
                let column_index = line_source
                    .char_indices()
                    .map(|(i, _)| i)
                    .take_while(|i| *i < relative_index)
                    .count();

                if relative_index >= line_source.len()
                    || line_source.is_char_boundary(relative_index)
                {
                    column_index
                } else {
                    column_index - 1
                }
            },
        }
    }

    /// The 1-indexed column number at the given byte index.
    ///
    /// # Example
    ///
    /// ```rust
    /// use codespan_reporting::files::Line;
    ///
    /// let line = Line {
    ///     start: 2,
    ///     number: 2,
    ///     source: "🗻∈🌏",
    /// };
    ///
    /// assert_eq!(line.column_number(0), 1);
    /// assert_eq!(line.column_number(line.start + 0), 1);
    /// assert_eq!(line.column_number(line.start + 1), 1);
    /// assert_eq!(line.column_number(line.start + 4), 2);
    /// assert_eq!(line.column_number(line.start + 8), 3);
    /// assert_eq!(line.column_number(line.start + line.source.len()), 4);
    /// ```
    pub fn column_number(&self, byte_index: usize) -> usize {
        self.column_index(byte_index) + 1
    }
}

/// Files that can be used for pretty printing.
///
/// A lifetime parameter `'a` is provided to allow any of the returned values to returned by reference.
/// This is to workaround the lack of higher kinded lifetime parameters.
/// This can be ignored if this is not needed, however.
pub trait Files<'a> {
    type FileId: 'a + Copy + PartialEq + PartialOrd + Eq + Ord + std::hash::Hash;
    type Origin: 'a + std::fmt::Display;
    type LineSource: 'a + AsRef<str>;

    /// The origin of a file.
    fn origin(&'a self, id: Self::FileId) -> Option<Self::Origin>;

    /// The line at the given index.
    fn line(&'a self, id: Self::FileId, line_index: usize) -> Option<Line<Self::LineSource>>;

    /// The index of the line at the given byte index.
    fn line_index(&'a self, id: Self::FileId, byte_index: usize) -> Option<usize>;
}

/// A single source file.
///
/// This is useful for simple language tests, but it might be worth creating a
/// custom implementation when a language scales beyond a certain size.
#[derive(Debug, Clone)]
pub struct SimpleFile<Origin, Source> {
    /// The origin of the file.
    origin: Origin,
    /// The source code of the file.
    source: Source,
    /// The starting byte indices in the source code.
    line_starts: Vec<usize>,
}

fn line_starts<'a>(source: &'a str) -> impl 'a + Iterator<Item = usize> {
    std::iter::once(0).chain(source.match_indices('\n').map(|(i, _)| i + 1))
}

impl<Origin, Source> SimpleFile<Origin, Source>
where
    Origin: std::fmt::Display,
    Source: AsRef<str>,
{
    /// Create a new source file.
    pub fn new(origin: Origin, source: Source) -> SimpleFile<Origin, Source> {
        SimpleFile {
            origin,
            line_starts: line_starts(source.as_ref()).collect(),
            source,
        }
    }

    /// Return the origin of the file.
    pub fn origin(&self) -> &Origin {
        &self.origin
    }

    /// Return the source of the file.
    pub fn source(&self) -> &Source {
        &self.source
    }

    fn line_start(&self, line_index: usize) -> Option<usize> {
        use std::cmp::Ordering;

        match line_index.cmp(&self.line_starts.len()) {
            Ordering::Less => self.line_starts.get(line_index).cloned(),
            Ordering::Equal => Some(self.source.as_ref().len()),
            Ordering::Greater => None,
        }
    }

    fn line_range(&self, line_index: usize) -> Option<Range<usize>> {
        let line_start = self.line_start(line_index)?;
        let next_line_start = self.line_start(line_index + 1)?;

        Some(line_start..next_line_start)
    }
}

impl<'a, Origin, Source> Files<'a> for SimpleFile<Origin, Source>
where
    Origin: 'a + std::fmt::Display + Clone,
    Source: 'a + AsRef<str>,
{
    type FileId = ();
    type Origin = Origin;
    type LineSource = String;

    fn origin(&self, (): ()) -> Option<Origin> {
        Some(self.origin.clone())
    }

    fn line_index(&self, (): (), byte_index: usize) -> Option<usize> {
        match self.line_starts.binary_search(&byte_index) {
            Ok(line) => Some(line),
            Err(next_line) => Some(next_line - 1),
        }
    }

    fn line(&self, (): (), line_index: usize) -> Option<Line<String>> {
        let range = self.line_range(line_index)?;

        Some(Line {
            start: range.start,
            number: line_index + 1,
            source: self.source.as_ref()[range].to_owned(),
        })
    }
}

/// A file database that can store multiple source files.
///
/// This is useful for simple language tests, but it might be worth creating a
/// custom implementation when a language scales beyond a certain size.
#[derive(Debug, Clone)]
pub struct SimpleFiles<Origin, Source> {
    files: Vec<SimpleFile<Origin, Source>>,
}

impl<Origin, Source> SimpleFiles<Origin, Source>
where
    Origin: std::fmt::Display,
    Source: AsRef<str>,
{
    /// Create a new files database.
    pub fn new() -> SimpleFiles<Origin, Source> {
        SimpleFiles { files: Vec::new() }
    }

    /// Add a file to the database, returning the handle that can be used to
    /// refer to it again.
    pub fn add(&mut self, origin: Origin, source: Source) -> usize {
        let file_id = self.files.len();
        self.files.push(SimpleFile::new(origin, source));
        file_id
    }

    /// Get the file corresponding to the given id.
    pub fn get(&self, file_id: usize) -> Option<&SimpleFile<Origin, Source>> {
        self.files.get(file_id)
    }
}

impl<'a, Origin, Source> Files<'a> for SimpleFiles<Origin, Source>
where
    Origin: 'a + std::fmt::Display + Clone,
    Source: 'a + AsRef<str>,
{
    type FileId = usize;
    type Origin = Origin;
    type LineSource = String;

    fn origin(&self, file_id: usize) -> Option<Origin> {
        Some(self.get(file_id)?.origin().clone())
    }

    fn line_index(&self, file_id: usize, byte_index: usize) -> Option<usize> {
        self.get(file_id)?.line_index((), byte_index)
    }

    fn line(&self, file_id: usize, line_index: usize) -> Option<Line<String>> {
        self.get(file_id)?.line((), line_index)
    }
}

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

    const TEST_SOURCE: &str = "foo\nbar\r\n\nbaz";

    #[test]
    fn line_starts() {
        let file = SimpleFile::new("test", TEST_SOURCE);

        assert_eq!(
            file.line_starts,
            [
                0,  // "foo\n"
                4,  // "bar\r\n"
                9,  // ""
                10, // "baz"
            ],
        );
    }

    #[test]
    fn line_span_sources() {
        let file = SimpleFile::new("test", TEST_SOURCE);

        let line_sources = (0..4)
            .map(|line| {
                let line_range = file.line_range(line).unwrap();
                &file.source[line_range]
            })
            .collect::<Vec<_>>();

        assert_eq!(line_sources, ["foo\n", "bar\r\n", "\n", "baz"]);
    }
}
<commit_msg>Clean up conditional<commit_after>//! Source file support for diagnostic reporting.

use std::ops::Range;

/// A line within a source file.
pub struct Line<Source> {
    /// The starting byte index of the line.
    pub start: usize,
    /// The line number.
    pub number: usize,
    /// The source of the line.
    pub source: Source,
}

impl<Source> Line<Source>
where
    Source: AsRef<str>,
{
    /// The column index at the given byte index in the source file.
    /// This is the number of characters to the given byte index.
    ///
    /// If the byte index is smaller than the start of the line, then `0` is returned.
    /// If the byte index is past the end of the line, the column index of the last
    /// character `+ 1` is returned.
    ///
    /// # Example
    ///
    /// ```rust
    /// use codespan_reporting::files::Line;
    ///
    /// let line = Line {
    ///     start: 2,
    ///     number: 2,
    ///     source: "🗻∈🌏",
    /// };
    ///
    /// assert_eq!(line.column_index(0), 0);
    /// assert_eq!(line.column_index(line.start + 0), 0);
    /// assert_eq!(line.column_index(line.start + 1), 0);
    /// assert_eq!(line.column_index(line.start + 4), 1);
    /// assert_eq!(line.column_index(line.start + 8), 2);
    /// assert_eq!(line.column_index(line.start + line.source.len()), 3);
    /// ```
    pub fn column_index(&self, byte_index: usize) -> usize {
        match byte_index.checked_sub(self.start) {
            None => 0,
            Some(relative_index) => {
                let line_source = self.source.as_ref();
                let column_index = line_source
                    .char_indices()
                    .map(|(i, _)| i)
                    .take_while(|i| *i < relative_index)
                    .count();

                match () {
                    () if relative_index >= line_source.len() => column_index,
                    () if line_source.is_char_boundary(relative_index) => column_index,
                    () => column_index - 1,
                }
            },
        }
    }

    /// The 1-indexed column number at the given byte index.
    ///
    /// # Example
    ///
    /// ```rust
    /// use codespan_reporting::files::Line;
    ///
    /// let line = Line {
    ///     start: 2,
    ///     number: 2,
    ///     source: "🗻∈🌏",
    /// };
    ///
    /// assert_eq!(line.column_number(0), 1);
    /// assert_eq!(line.column_number(line.start + 0), 1);
    /// assert_eq!(line.column_number(line.start + 1), 1);
    /// assert_eq!(line.column_number(line.start + 4), 2);
    /// assert_eq!(line.column_number(line.start + 8), 3);
    /// assert_eq!(line.column_number(line.start + line.source.len()), 4);
    /// ```
    pub fn column_number(&self, byte_index: usize) -> usize {
        self.column_index(byte_index) + 1
    }
}

/// Files that can be used for pretty printing.
///
/// A lifetime parameter `'a` is provided to allow any of the returned values to returned by reference.
/// This is to workaround the lack of higher kinded lifetime parameters.
/// This can be ignored if this is not needed, however.
pub trait Files<'a> {
    type FileId: 'a + Copy + PartialEq + PartialOrd + Eq + Ord + std::hash::Hash;
    type Origin: 'a + std::fmt::Display;
    type LineSource: 'a + AsRef<str>;

    /// The origin of a file.
    fn origin(&'a self, id: Self::FileId) -> Option<Self::Origin>;

    /// The line at the given index.
    fn line(&'a self, id: Self::FileId, line_index: usize) -> Option<Line<Self::LineSource>>;

    /// The index of the line at the given byte index.
    fn line_index(&'a self, id: Self::FileId, byte_index: usize) -> Option<usize>;
}

/// A single source file.
///
/// This is useful for simple language tests, but it might be worth creating a
/// custom implementation when a language scales beyond a certain size.
#[derive(Debug, Clone)]
pub struct SimpleFile<Origin, Source> {
    /// The origin of the file.
    origin: Origin,
    /// The source code of the file.
    source: Source,
    /// The starting byte indices in the source code.
    line_starts: Vec<usize>,
}

fn line_starts<'a>(source: &'a str) -> impl 'a + Iterator<Item = usize> {
    std::iter::once(0).chain(source.match_indices('\n').map(|(i, _)| i + 1))
}

impl<Origin, Source> SimpleFile<Origin, Source>
where
    Origin: std::fmt::Display,
    Source: AsRef<str>,
{
    /// Create a new source file.
    pub fn new(origin: Origin, source: Source) -> SimpleFile<Origin, Source> {
        SimpleFile {
            origin,
            line_starts: line_starts(source.as_ref()).collect(),
            source,
        }
    }

    /// Return the origin of the file.
    pub fn origin(&self) -> &Origin {
        &self.origin
    }

    /// Return the source of the file.
    pub fn source(&self) -> &Source {
        &self.source
    }

    fn line_start(&self, line_index: usize) -> Option<usize> {
        use std::cmp::Ordering;

        match line_index.cmp(&self.line_starts.len()) {
            Ordering::Less => self.line_starts.get(line_index).cloned(),
            Ordering::Equal => Some(self.source.as_ref().len()),
            Ordering::Greater => None,
        }
    }

    fn line_range(&self, line_index: usize) -> Option<Range<usize>> {
        let line_start = self.line_start(line_index)?;
        let next_line_start = self.line_start(line_index + 1)?;

        Some(line_start..next_line_start)
    }
}

impl<'a, Origin, Source> Files<'a> for SimpleFile<Origin, Source>
where
    Origin: 'a + std::fmt::Display + Clone,
    Source: 'a + AsRef<str>,
{
    type FileId = ();
    type Origin = Origin;
    type LineSource = String;

    fn origin(&self, (): ()) -> Option<Origin> {
        Some(self.origin.clone())
    }

    fn line_index(&self, (): (), byte_index: usize) -> Option<usize> {
        match self.line_starts.binary_search(&byte_index) {
            Ok(line) => Some(line),
            Err(next_line) => Some(next_line - 1),
        }
    }

    fn line(&self, (): (), line_index: usize) -> Option<Line<String>> {
        let range = self.line_range(line_index)?;

        Some(Line {
            start: range.start,
            number: line_index + 1,
            source: self.source.as_ref()[range].to_owned(),
        })
    }
}

/// A file database that can store multiple source files.
///
/// This is useful for simple language tests, but it might be worth creating a
/// custom implementation when a language scales beyond a certain size.
#[derive(Debug, Clone)]
pub struct SimpleFiles<Origin, Source> {
    files: Vec<SimpleFile<Origin, Source>>,
}

impl<Origin, Source> SimpleFiles<Origin, Source>
where
    Origin: std::fmt::Display,
    Source: AsRef<str>,
{
    /// Create a new files database.
    pub fn new() -> SimpleFiles<Origin, Source> {
        SimpleFiles { files: Vec::new() }
    }

    /// Add a file to the database, returning the handle that can be used to
    /// refer to it again.
    pub fn add(&mut self, origin: Origin, source: Source) -> usize {
        let file_id = self.files.len();
        self.files.push(SimpleFile::new(origin, source));
        file_id
    }

    /// Get the file corresponding to the given id.
    pub fn get(&self, file_id: usize) -> Option<&SimpleFile<Origin, Source>> {
        self.files.get(file_id)
    }
}

impl<'a, Origin, Source> Files<'a> for SimpleFiles<Origin, Source>
where
    Origin: 'a + std::fmt::Display + Clone,
    Source: 'a + AsRef<str>,
{
    type FileId = usize;
    type Origin = Origin;
    type LineSource = String;

    fn origin(&self, file_id: usize) -> Option<Origin> {
        Some(self.get(file_id)?.origin().clone())
    }

    fn line_index(&self, file_id: usize, byte_index: usize) -> Option<usize> {
        self.get(file_id)?.line_index((), byte_index)
    }

    fn line(&self, file_id: usize, line_index: usize) -> Option<Line<String>> {
        self.get(file_id)?.line((), line_index)
    }
}

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

    const TEST_SOURCE: &str = "foo\nbar\r\n\nbaz";

    #[test]
    fn line_starts() {
        let file = SimpleFile::new("test", TEST_SOURCE);

        assert_eq!(
            file.line_starts,
            [
                0,  // "foo\n"
                4,  // "bar\r\n"
                9,  // ""
                10, // "baz"
            ],
        );
    }

    #[test]
    fn line_span_sources() {
        let file = SimpleFile::new("test", TEST_SOURCE);

        let line_sources = (0..4)
            .map(|line| {
                let line_range = file.line_range(line).unwrap();
                &file.source[line_range]
            })
            .collect::<Vec<_>>();

        assert_eq!(line_sources, ["foo\n", "bar\r\n", "\n", "baz"]);
    }
}
<|endoftext|>


<commit_before>//! Messages used in the Exonum consensus algorithm.
//!
//! Every message, unless stated otherwise, is checked by the same set of rules. The message is
//! ignored if it
//!     * is sent from a lower height than the current one
//!     * contains incorrect validator id
//!     * is signed with incorrect signature
//!
//! Specific nuances are described in each message documentation and typically consist of three
//! parts:
//!     * validation - additional checks before processing
//!     * processing - how message is processed and result of the processing
//!     * generation - in which cases message is generated

use std::net::SocketAddr;
use std::time::SystemTime;

use crypto::{Hash, PublicKey};
use blockchain;
use super::{RawMessage, BitVec};

pub const CONSENSUS: u16 = 0;

pub const CONNECT_MESSAGE_ID: u16 = 0;
pub const STATUS_MESSAGE_ID: u16 = 1;

pub const PROPOSE_MESSAGE_ID: u16 = 2;
pub const PREVOTE_MESSAGE_ID: u16 = 3;
pub const PRECOMMIT_MESSAGE_ID: u16 = 4;
pub const BLOCK_MESSAGE_ID: u16 = 5;

pub const REQUEST_PROPOSE_MESSAGE_ID: u16 = 6;
pub const REQUEST_TRANSACTIONS_MESSAGE_ID: u16 = 7;
pub const REQUEST_PREVOTES_MESSAGE_ID: u16 = 8;
pub const REQUEST_PEERS_MESSAGE_ID: u16 = 9;
pub const REQUEST_BLOCK_MESSAGE_ID: u16 = 10;

message! {
/// Connect to a node.
///
/// ### Validation
/// The message is ignored if its time is earlier than in the previous `Connect` message received
/// from the same peer.
///
/// ### Processing
/// Connect to the peer.
///
/// ### Generation
/// A node sends `Connect` message to all known addresses during initialization. Additionally,
/// the node responds by its own `Connect` message after receiving `node::Event::Connected`.
    struct Connect {
        const TYPE = CONSENSUS;
        const ID = CONNECT_MESSAGE_ID;
        const SIZE = 50;

        field pub_key:        &PublicKey  [00 => 32]
        field addr:           SocketAddr  [32 => 38]
        field time:           SystemTime  [38 => 50]
    }
}

message! {
/// Proposal for a new block.
///
/// ### Validation
/// The message is ignored if it
///     * contains incorrect `prev_hash`
///     * is sent by non-leader
///     * contains already committed transactions
///     * is already known
///
/// ### Processing
/// If the message contains unknown transactions, then `RequestTransactions` is sent in reply.
/// Otherwise `Prevote` is broadcast.
///
/// ### Generation
/// A node broadcasts `Propose` if it is a leader and is not locked for a different proposal. Also
/// `Propose` can be sent as response to `RequestPropose`.
    struct Propose {
        const TYPE = CONSENSUS;
        const ID = PROPOSE_MESSAGE_ID;
        const SIZE = 54;

        field validator:      u16         [00 => 02]
        field height:         u64         [02 => 10]
        field round:          u32         [10 => 14]
        field prev_hash:      &Hash       [14 => 46]
        field transactions:   &[Hash]     [46 => 54]
    }
}

message! {
/// Pre-vote for a new block.
///
/// ### Validation
/// A node panics if it has already sent a different `Prevote` for the same round.
///
/// ### Processing
/// Pre-vote is added to the list of known votes for the same proposal.
/// If `locked_round` number from the message is bigger than in a node state, then a node replies
/// with `RequestPrevotes`.
/// If there are unknown transactions in the propose specified by `propose_hash`,
/// `RequestTransactions` is sent in reply.
/// Otherwise if all transactions are known and there are +2/3 pre-votes, then a node is locked
/// to that proposal and `Precommit` is broadcast.
///
/// ### Generation
/// A node broadcasts `Prevote` in response to `Propose` when it has received all the transactions.
    struct Prevote {
        const TYPE = CONSENSUS;
        const ID = PREVOTE_MESSAGE_ID;
        const SIZE = 50;

        field validator:      u16         [00 => 02]
        field height:         u64         [02 => 10]
        field round:          u32         [10 => 14]
        field propose_hash:   &Hash       [14 => 46]
        field locked_round:   u32         [46 => 50]
    }
}

message! {
/// Pre-commit for a proposal.
///
/// ### Validation
/// A node panics if it  has already sent a different `Precommit` for the same round.
///
/// ### Processing
/// Pre-commit is added to the list of known pre-commits.
/// If a proposal is unknown to the node, `RequestPropose` is sent in reply.
/// If `round` number from the message is bigger than a node's "locked round", then a node replies
/// with `RequestPrevotes`.
/// If there are unknown transactions, then `RequestTransactions` is sent in reply.
/// If a validator receives +2/3 precommits for the same proposal with the same block_hash, then
/// block is executed and `Status` is broadcast.
///
/// ### Generation
/// A node broadcasts `Precommit` in response to `Prevote` if there are +2/3 pre-votes and no
/// unknown transactions.
    struct Precommit {
        const TYPE = CONSENSUS;
        const ID = PRECOMMIT_MESSAGE_ID;
        const SIZE = 94;

        field validator:      u16         [00 => 02]
        field height:         u64         [06 => 14]
        field round:          u32         [14 => 18]
        field propose_hash:   &Hash       [18 => 50]
        field block_hash:     &Hash       [50 => 82]
        field time:           SystemTime  [82 => 94]
    }
}

message! {
/// Current node status.
///
/// ### Validation
/// The message is ignored if its signature is incorrect or its `height` is lower than a node's
/// height.
///
/// ### Processing
/// If the message's `height` number is bigger than a node's one, then `RequestBlock` with current
/// node's height is sent in reply.
///
/// ### Generation
/// `Status` message is broadcast regularly with the timeout controlled by
/// `blockchain::ConsensusConfig::status_timeout`. Also, it is broadcast after accepting a new
/// block.
    struct Status {
        const TYPE = CONSENSUS;
        const ID = STATUS_MESSAGE_ID;
        const SIZE = 72;

        field from:           &PublicKey          [00 => 32]
        field height:         u64                 [32 => 40]
        field last_hash:      &Hash               [40 => 72]
    }
}

message! {
/// Information about a block.
///
/// ### Validation
/// The message is ignored if
///     * its `to` field corresponds to a different node
///     * the `block`, `transaction` and `precommits` fields cannot be parsed or verified
///
/// ### Processing
/// The block is added to the blockchain.
///
/// ### Generation
/// The message is sent as response to `RequestBlock`.
    struct Block {
        const TYPE = CONSENSUS;
        const ID = BLOCK_MESSAGE_ID;
        const SIZE = 88;

        field from:           &PublicKey          [00 => 32]
        field to:             &PublicKey          [32 => 64]
        field block:          blockchain::Block   [64 => 72]
        field precommits:     Vec<Precommit>      [72 => 80]
        field transactions:   Vec<RawMessage>     [80 => 88]
    }
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct BlockProof {
    pub block: blockchain::Block,
    pub precommits: Vec<Precommit>,
}

message! {
/// Request for the `Propose`.
///
/// ### Validation
/// The message is ignored if its `height` is not equal to the node's height.
///
/// ### Processing
/// `Propose` is sent as the response.
///
/// ### Generation
/// A node can send `RequestPropose` during `Precommit` handling.
    struct RequestPropose {
        const TYPE = CONSENSUS;
        const ID = REQUEST_PROPOSE_MESSAGE_ID;
        const SIZE = 104;

        field from:           &PublicKey  [00 => 32]
        field to:             &PublicKey  [32 => 64]
        field height:         u64         [64 => 72]
        field propose_hash:   &Hash       [72 => 104]
    }
}

message! {
/// Request for transactions by hash.
///
/// ### Processing
/// Requested transactions are sent to the recipient.
///
/// ### Generation
/// This message can be sent during `Propose`, `Prevote` and `Precommit` handling.
    struct RequestTransactions {
        const TYPE = CONSENSUS;
        const ID = REQUEST_TRANSACTIONS_MESSAGE_ID;
        const SIZE = 72;

        field from:           &PublicKey  [00 => 32]
        field to:             &PublicKey  [32 => 64]
        field txs:            &[Hash]     [64 => 72]
    }
}

message! {
/// Request for pre-votes.
///
/// ### Validation
/// The message is ignored if its `height` is not equal to the node's height.
///
/// ### Processing
/// The requested pre-votes are sent to the recipient.
///
/// ### Generation
/// This message can be sent during `Prevote` and `Precommit` handling.
    struct RequestPrevotes {
        const TYPE = CONSENSUS;
        const ID = REQUEST_PREVOTES_MESSAGE_ID;
        const SIZE = 116;

        field from:           &PublicKey  [00 => 32]
        field to:             &PublicKey  [32 => 64]
        field height:         u64         [64 => 72]
        field round:          u32         [72 => 76]
        field propose_hash:   &Hash       [76 => 108]
        field validators:     BitVec      [108 => 116]
    }
}

message! {
/// Request connected peers from a node.
///
/// ### Validation
/// Request is considered valid if the sender of the message on the network level corresponds to
/// the `from` field.
///
/// ### Processing
/// Peer `Connect` messages are sent to the recipient.
///
/// ### Generation
/// `RequestPeers` message is sent regularly with the timeout controlled by
/// `blockchain::ConsensusConfig::peers_timeout`.
    struct RequestPeers {
        const TYPE = CONSENSUS;
        const ID = REQUEST_PEERS_MESSAGE_ID;
        const SIZE = 64;

        field from:           &PublicKey  [00 => 32]
        field to:             &PublicKey  [32 => 64]
    }
}

message! {
/// Request for the block with the given `height`.
///
/// ### Validation
/// The message is ignored if its `height` is bigger than the node's one.
///
/// ### Processing
/// `Block` message is sent as the response.
///
/// ### Generation
/// This message can be sent during `Status` processing.
    struct RequestBlock {
        const TYPE = CONSENSUS;
        const ID = REQUEST_BLOCK_MESSAGE_ID;
        const SIZE = 72;

        field from:           &PublicKey  [00 => 32]
        field to:             &PublicKey  [32 => 64]
        field height:         u64         [64 => 72]
    }
}
<commit_msg>Fix comment<commit_after>//! Messages used in the Exonum consensus algorithm.
//!
//! Every message, unless stated otherwise, is checked by the same set of rules. The message is
//! ignored if it
//!     * is sent from a lower height than the current one
//!     * contains incorrect validator id
//!     * is signed with incorrect signature
//!
//! Specific nuances are described in each message documentation and typically consist of three
//! parts:
//!     * validation - additional checks before processing
//!     * processing - how message is processed and result of the processing
//!     * generation - in which cases message is generated

use std::net::SocketAddr;
use std::time::SystemTime;

use crypto::{Hash, PublicKey};
use blockchain;
use super::{RawMessage, BitVec};

pub const CONSENSUS: u16 = 0;

pub const CONNECT_MESSAGE_ID: u16 = 0;
pub const STATUS_MESSAGE_ID: u16 = 1;

pub const PROPOSE_MESSAGE_ID: u16 = 2;
pub const PREVOTE_MESSAGE_ID: u16 = 3;
pub const PRECOMMIT_MESSAGE_ID: u16 = 4;
pub const BLOCK_MESSAGE_ID: u16 = 5;

pub const REQUEST_PROPOSE_MESSAGE_ID: u16 = 6;
pub const REQUEST_TRANSACTIONS_MESSAGE_ID: u16 = 7;
pub const REQUEST_PREVOTES_MESSAGE_ID: u16 = 8;
pub const REQUEST_PEERS_MESSAGE_ID: u16 = 9;
pub const REQUEST_BLOCK_MESSAGE_ID: u16 = 10;

message! {
/// Connect to a node.
///
/// ### Validation
/// The message is ignored if its time is earlier than in the previous `Connect` message received
/// from the same peer.
///
/// ### Processing
/// Connect to the peer.
///
/// ### Generation
/// A node sends `Connect` message to all known addresses during initialization. Additionally,
/// the node responds by its own `Connect` message after receiving `node::Event::Connected`.
    struct Connect {
        const TYPE = CONSENSUS;
        const ID = CONNECT_MESSAGE_ID;
        const SIZE = 50;

        field pub_key:        &PublicKey  [00 => 32]
        field addr:           SocketAddr  [32 => 38]
        field time:           SystemTime  [38 => 50]
    }
}

message! {
/// Proposal for a new block.
///
/// ### Validation
/// The message is ignored if it
///     * contains incorrect `prev_hash`
///     * is sent by non-leader
///     * contains already committed transactions
///     * is already known
///
/// ### Processing
/// If the message contains unknown transactions, then `RequestTransactions` is sent in reply.
/// Otherwise `Prevote` is broadcast.
///
/// ### Generation
/// A node broadcasts `Propose` if it is a leader and is not locked for a different proposal. Also
/// `Propose` can be sent as response to `RequestPropose`.
    struct Propose {
        const TYPE = CONSENSUS;
        const ID = PROPOSE_MESSAGE_ID;
        const SIZE = 54;

        field validator:      u16         [00 => 02]
        field height:         u64         [02 => 10]
        field round:          u32         [10 => 14]
        field prev_hash:      &Hash       [14 => 46]
        field transactions:   &[Hash]     [46 => 54]
    }
}

message! {
/// Pre-vote for a new block.
///
/// ### Validation
/// A node panics if it has already sent a different `Prevote` for the same round.
///
/// ### Processing
/// Pre-vote is added to the list of known votes for the same proposal.
/// If `locked_round` number from the message is bigger than in a node state, then a node replies
/// with `RequestPrevotes`.
/// If there are unknown transactions in the propose specified by `propose_hash`,
/// `RequestTransactions` is sent in reply.
/// Otherwise if all transactions are known and there are +2/3 pre-votes, then a node is locked
/// to that proposal and `Precommit` is broadcast.
///
/// ### Generation
/// A node broadcasts `Prevote` in response to `Propose` when it has received all the transactions.
    struct Prevote {
        const TYPE = CONSENSUS;
        const ID = PREVOTE_MESSAGE_ID;
        const SIZE = 50;

        field validator:      u16         [00 => 02]
        field height:         u64         [02 => 10]
        field round:          u32         [10 => 14]
        field propose_hash:   &Hash       [14 => 46]
        field locked_round:   u32         [46 => 50]
    }
}

message! {
/// Pre-commit for a proposal.
///
/// ### Validation
/// A node panics if it  has already sent a different `Precommit` for the same round.
///
/// ### Processing
/// Pre-commit is added to the list of known pre-commits.
/// If a proposal is unknown to the node, `RequestPropose` is sent in reply.
/// If `round` number from the message is bigger than a node's "locked round", then a node replies
/// with `RequestPrevotes`.
/// If there are unknown transactions, then `RequestTransactions` is sent in reply.
/// If a validator receives +2/3 precommits for the same proposal with the same block_hash, then
/// block is executed and `Status` is broadcast.
///
/// ### Generation
/// A node broadcasts `Precommit` in response to `Prevote` if there are +2/3 pre-votes and no
/// unknown transactions.
    struct Precommit {
        const TYPE = CONSENSUS;
        const ID = PRECOMMIT_MESSAGE_ID;
        const SIZE = 94;

        field validator:      u16         [00 => 02]
        field height:         u64         [06 => 14]
        field round:          u32         [14 => 18]
        field propose_hash:   &Hash       [18 => 50]
        field block_hash:     &Hash       [50 => 82]
        field time:           SystemTime  [82 => 94]
    }
}

message! {
/// Current node status.
///
/// ### Validation
/// The message is ignored if its signature is incorrect or its `height` is lower than a node's
/// height.
///
/// ### Processing
/// If the message's `height` number is bigger than a node's one, then `RequestBlock` with current
/// node's height is sent in reply.
///
/// ### Generation
/// `Status` message is broadcast regularly with the timeout controlled by
/// `blockchain::ConsensusConfig::status_timeout`. Also, it is broadcast after accepting a new
/// block.
    struct Status {
        const TYPE = CONSENSUS;
        const ID = STATUS_MESSAGE_ID;
        const SIZE = 72;

        field from:           &PublicKey          [00 => 32]
        field height:         u64                 [32 => 40]
        field last_hash:      &Hash               [40 => 72]
    }
}

message! {
/// Information about a block.
///
/// ### Validation
/// The message is ignored if
///     * its `to` field corresponds to a different node
///     * the `block`, `transaction` and `precommits` fields cannot be parsed or verified
///
/// ### Processing
/// The block is added to the blockchain.
///
/// ### Generation
/// The message is sent as response to `RequestBlock`.
    struct Block {
        const TYPE = CONSENSUS;
        const ID = BLOCK_MESSAGE_ID;
        const SIZE = 88;

        field from:           &PublicKey          [00 => 32]
        field to:             &PublicKey          [32 => 64]
        field block:          blockchain::Block   [64 => 72]
        field precommits:     Vec<Precommit>      [72 => 80]
        field transactions:   Vec<RawMessage>     [80 => 88]
    }
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct BlockProof {
    pub block: blockchain::Block,
    pub precommits: Vec<Precommit>,
}

message! {
/// Request for the `Propose`.
///
/// ### Validation
/// The message is ignored if its `height` is not equal to the node's height.
///
/// ### Processing
/// `Propose` is sent as the response.
///
/// ### Generation
/// A node can send `RequestPropose` during `Precommit` and `Prevote` handling.
    struct RequestPropose {
        const TYPE = CONSENSUS;
        const ID = REQUEST_PROPOSE_MESSAGE_ID;
        const SIZE = 104;

        field from:           &PublicKey  [00 => 32]
        field to:             &PublicKey  [32 => 64]
        field height:         u64         [64 => 72]
        field propose_hash:   &Hash       [72 => 104]
    }
}

message! {
/// Request for transactions by hash.
///
/// ### Processing
/// Requested transactions are sent to the recipient.
///
/// ### Generation
/// This message can be sent during `Propose`, `Prevote` and `Precommit` handling.
    struct RequestTransactions {
        const TYPE = CONSENSUS;
        const ID = REQUEST_TRANSACTIONS_MESSAGE_ID;
        const SIZE = 72;

        field from:           &PublicKey  [00 => 32]
        field to:             &PublicKey  [32 => 64]
        field txs:            &[Hash]     [64 => 72]
    }
}

message! {
/// Request for pre-votes.
///
/// ### Validation
/// The message is ignored if its `height` is not equal to the node's height.
///
/// ### Processing
/// The requested pre-votes are sent to the recipient.
///
/// ### Generation
/// This message can be sent during `Prevote` and `Precommit` handling.
    struct RequestPrevotes {
        const TYPE = CONSENSUS;
        const ID = REQUEST_PREVOTES_MESSAGE_ID;
        const SIZE = 116;

        field from:           &PublicKey  [00 => 32]
        field to:             &PublicKey  [32 => 64]
        field height:         u64         [64 => 72]
        field round:          u32         [72 => 76]
        field propose_hash:   &Hash       [76 => 108]
        field validators:     BitVec      [108 => 116]
    }
}

message! {
/// Request connected peers from a node.
///
/// ### Validation
/// Request is considered valid if the sender of the message on the network level corresponds to
/// the `from` field.
///
/// ### Processing
/// Peer `Connect` messages are sent to the recipient.
///
/// ### Generation
/// `RequestPeers` message is sent regularly with the timeout controlled by
/// `blockchain::ConsensusConfig::peers_timeout`.
    struct RequestPeers {
        const TYPE = CONSENSUS;
        const ID = REQUEST_PEERS_MESSAGE_ID;
        const SIZE = 64;

        field from:           &PublicKey  [00 => 32]
        field to:             &PublicKey  [32 => 64]
    }
}

message! {
/// Request for the block with the given `height`.
///
/// ### Validation
/// The message is ignored if its `height` is bigger than the node's one.
///
/// ### Processing
/// `Block` message is sent as the response.
///
/// ### Generation
/// This message can be sent during `Status` processing.
    struct RequestBlock {
        const TYPE = CONSENSUS;
        const ID = REQUEST_BLOCK_MESSAGE_ID;
        const SIZE = 72;

        field from:           &PublicKey  [00 => 32]
        field to:             &PublicKey  [32 => 64]
        field height:         u64         [64 => 72]
    }
}
<|endoftext|>


<commit_before>#![feature(box_syntax)]
#![feature(plugin)]

#![unstable]

#[plugin]
#[no_link]
extern crate compile_msg;

extern crate libc;

use std::ffi::{CString};
use std::sync::mpsc::{Sender};
use std::sync::Mutex;
use std::thread::Thread;

#[doc(hidden)]
pub mod ffi;

/// This static variable  will store the android_app* on creation, and set it back to 0 at
///  destruction.
/// Apart from this, the static is never written, so there is no risk of race condition.
static mut ANDROID_APP: *mut ffi::android_app = 0 as *mut ffi::android_app;

/// This is the structure that serves as user data in the android_app*
#[doc(hidden)]
struct Context {
    senders: Mutex<Vec<Sender<Event>>>,
}

/// An event triggered by the Android environment.
pub enum Event {
    EventUp,
    EventDown,
    EventMove(i32, i32),
}

impl Copy for Event {}

#[cfg(not(target_os = "android"))]
compile_note!("You are not compiling for Android");

#[macro_export]
macro_rules! android_start(
    ($main: ident) => (
        pub mod __android_start {
            extern crate android_glue;

            // this function is here because we are sure that it will be included by the linker
            // so we call app_dummy in it, in order to be sure that the native glue will be included
            #[start]
            pub fn start(_: int, _: *const *const u8) -> int {
                unsafe { android_glue::ffi::app_dummy() };
                1
            }

            #[no_mangle]
            #[inline(never)]
            #[allow(non_snake_case)]
            pub extern "C" fn android_main(app: *mut ()) {
                android_glue::android_main2(app, move|| super::$main());
            }
        }
    )
);

/// This is the function that must be called by `android_main`
#[doc(hidden)]
pub fn android_main2<F>(app: *mut (), main_function: F)
    where F: FnOnce(), F: Send
{
    use std::{mem, ptr};

    write_log("Entering android_main");

    unsafe { ANDROID_APP = std::mem::transmute(app) };
    let app: &mut ffi::android_app = unsafe { std::mem::transmute(app) };

    // creating the context that will be passed to the callback
    let context = Context { senders: Mutex::new(Vec::new()) };
    app.onAppCmd = commands_callback;
    app.onInputEvent = inputs_callback;
    app.userData = unsafe { std::mem::transmute(&context) };

    // executing the main function in parallel
    let g = Thread::spawn(move|| {
        std::old_io::stdio::set_stdout(box std::old_io::LineBufferedWriter::new(ToLogWriter));
        std::old_io::stdio::set_stderr(box std::old_io::LineBufferedWriter::new(ToLogWriter));
        main_function()
    });

    // polling for events forever
    // note that this must be done in the same thread as android_main because ALooper are
    //  thread-local
    unsafe {
        loop {
            let mut events = mem::uninitialized();
            let mut source = mem::uninitialized();

            // passing -1 means that we are blocking
            let ident = ffi::ALooper_pollAll(-1, ptr::null_mut(), &mut events,
                &mut source);

            // processing the event
            if !source.is_null() {
                let source: *mut ffi::android_poll_source = mem::transmute(source);
                ((*source).process)(ANDROID_APP, source);
            }
        }
    }

    // terminating the application
    unsafe { ANDROID_APP = 0 as *mut ffi::android_app };
}

/// Writer that will redirect what is written to it to the logs.
struct ToLogWriter;

impl Writer for ToLogWriter {
    fn write(&mut self, buf: &[u8]) -> std::old_io::IoResult<()> {
        let message = CString::from_slice(buf).as_slice_with_nul().as_ptr();
        let tag = b"RustAndroidGlueStdouterr";
        let tag = CString::from_slice(tag).as_slice_with_nul().as_ptr();
        unsafe { ffi::__android_log_write(3, tag, message) };
        Ok(())
    }
}

/// The callback for inputs.
pub extern fn inputs_callback(_: *mut ffi::android_app, event: *const ffi::AInputEvent)
    -> libc::int32_t
{
    fn send_event(event: Event) {
        let senders = get_context().senders.lock().ok().unwrap();
        for sender in senders.iter() {
            sender.send(event);
        }
    }
    fn get_xy(event: *const ffi::AInputEvent) -> (i32, i32) {
        let x = unsafe { ffi::AMotionEvent_getX(event, 0) };
        let y = unsafe { ffi::AMotionEvent_getY(event, 0) };
        (x as i32, y as i32)
    }
    let action = unsafe { ffi::AMotionEvent_getAction(event) };
    let action_code = action & ffi::AMOTION_EVENT_ACTION_MASK;
    match action_code {
        ffi::AMOTION_EVENT_ACTION_UP
            | ffi::AMOTION_EVENT_ACTION_OUTSIDE
            | ffi::AMOTION_EVENT_ACTION_CANCEL
            | ffi::AMOTION_EVENT_ACTION_POINTER_UP =>
        {
            send_event(Event::EventUp);
        },
        ffi::AMOTION_EVENT_ACTION_DOWN
            | ffi::AMOTION_EVENT_ACTION_POINTER_DOWN =>
        {
            let (x, y) = get_xy(event);
            send_event(Event::EventMove(x, y));
            send_event(Event::EventDown);
        },
        _ => {
            let (x, y) = get_xy(event);
            send_event(Event::EventMove(x, y));
        },
    }
    0
}

/// The callback for commands.
#[doc(hidden)]
pub extern fn commands_callback(_: *mut ffi::android_app, command: libc::int32_t) {
    let context = get_context();

    match command {
        ffi::APP_CMD_INIT_WINDOW => {

        },

        ffi::APP_CMD_SAVE_STATE => {

        },

        ffi::APP_CMD_TERM_WINDOW => {

        },

        ffi::APP_CMD_GAINED_FOCUS => {

        },

        ffi::APP_CMD_LOST_FOCUS => {

        },

        _ => ()
    }
}

/// Returns the current Context.
fn get_context() -> &'static Context {
    let context = unsafe { (*ANDROID_APP).userData };
    unsafe { std::mem::transmute(context) }
}

/// Adds a sender where events will be sent to.
pub fn add_sender(sender: Sender<Event>) {
    get_context().senders.lock().ok().unwrap().push(sender);
}

/// Returns a handle to the native window.
pub unsafe fn get_native_window() -> ffi::NativeWindowType {
    if ANDROID_APP.is_null() {
        panic!("The application was not initialized from android_main");
    }

    loop {
        let value = (*ANDROID_APP).window;
        if !value.is_null() {
            return value;
        }

        // spin-locking
        std::old_io::timer::sleep(std::time::Duration::milliseconds(10));
    }
}

///
pub fn write_log(message: &str) {
    let message = message.as_bytes();
    let message = CString::from_slice(message).as_slice_with_nul().as_ptr();
    let tag = b"RustAndroidGlueStdouterr";
    let tag = CString::from_slice(tag).as_slice_with_nul().as_ptr();
    unsafe { ffi::__android_log_write(3, tag, message) };
}

pub enum AssetError {
    AssetMissing,
    EmptyBuffer,
}

pub fn load_asset(filename: &str) -> Result<Vec<u8>, AssetError> {
    struct AssetCloser {
        asset: *const ffi::Asset,
    }

    impl Drop for AssetCloser {
        fn drop(&mut self) {
            unsafe {
                ffi::AAsset_close(self.asset)
            };
        }
    }

    unsafe fn get_asset_manager() -> *const ffi::AAssetManager {
        let app = &*ANDROID_APP;
        let activity = &*app.activity;
        activity.assetManager
    }

    let filename_c_str = CString::from_slice(filename.as_bytes())
        .as_slice_with_nul().as_ptr();
    let asset = unsafe {
        ffi::AAssetManager_open(
            get_asset_manager(), filename_c_str, ffi::MODE_STREAMING)
    };
    if asset.is_null() {
        return Err(AssetError::AssetMissing);
    }
    let _asset_closer = AssetCloser{asset: asset};
    let len = unsafe {
        ffi::AAsset_getLength(asset)
    };
    let buff = unsafe {
        ffi::AAsset_getBuffer(asset)
    };
    if buff.is_null() {
        return Err(AssetError::EmptyBuffer);
    }
    let vec = unsafe {
        Vec::from_raw_buf(buff as *const u8, len as usize)
    };
    Ok(vec)
}
<commit_msg>Rename Writer::write to Writer::write_all.<commit_after>#![feature(box_syntax)]
#![feature(plugin)]

#![unstable]

#[plugin]
#[no_link]
extern crate compile_msg;

extern crate libc;

use std::ffi::{CString};
use std::sync::mpsc::{Sender};
use std::sync::Mutex;
use std::thread::Thread;

#[doc(hidden)]
pub mod ffi;

/// This static variable  will store the android_app* on creation, and set it back to 0 at
///  destruction.
/// Apart from this, the static is never written, so there is no risk of race condition.
static mut ANDROID_APP: *mut ffi::android_app = 0 as *mut ffi::android_app;

/// This is the structure that serves as user data in the android_app*
#[doc(hidden)]
struct Context {
    senders: Mutex<Vec<Sender<Event>>>,
}

/// An event triggered by the Android environment.
pub enum Event {
    EventUp,
    EventDown,
    EventMove(i32, i32),
}

impl Copy for Event {}

#[cfg(not(target_os = "android"))]
compile_note!("You are not compiling for Android");

#[macro_export]
macro_rules! android_start(
    ($main: ident) => (
        pub mod __android_start {
            extern crate android_glue;

            // this function is here because we are sure that it will be included by the linker
            // so we call app_dummy in it, in order to be sure that the native glue will be included
            #[start]
            pub fn start(_: int, _: *const *const u8) -> int {
                unsafe { android_glue::ffi::app_dummy() };
                1
            }

            #[no_mangle]
            #[inline(never)]
            #[allow(non_snake_case)]
            pub extern "C" fn android_main(app: *mut ()) {
                android_glue::android_main2(app, move|| super::$main());
            }
        }
    )
);

/// This is the function that must be called by `android_main`
#[doc(hidden)]
pub fn android_main2<F>(app: *mut (), main_function: F)
    where F: FnOnce(), F: Send
{
    use std::{mem, ptr};

    write_log("Entering android_main");

    unsafe { ANDROID_APP = std::mem::transmute(app) };
    let app: &mut ffi::android_app = unsafe { std::mem::transmute(app) };

    // creating the context that will be passed to the callback
    let context = Context { senders: Mutex::new(Vec::new()) };
    app.onAppCmd = commands_callback;
    app.onInputEvent = inputs_callback;
    app.userData = unsafe { std::mem::transmute(&context) };

    // executing the main function in parallel
    let g = Thread::spawn(move|| {
        std::old_io::stdio::set_stdout(box std::old_io::LineBufferedWriter::new(ToLogWriter));
        std::old_io::stdio::set_stderr(box std::old_io::LineBufferedWriter::new(ToLogWriter));
        main_function()
    });

    // polling for events forever
    // note that this must be done in the same thread as android_main because ALooper are
    //  thread-local
    unsafe {
        loop {
            let mut events = mem::uninitialized();
            let mut source = mem::uninitialized();

            // passing -1 means that we are blocking
            let ident = ffi::ALooper_pollAll(-1, ptr::null_mut(), &mut events,
                &mut source);

            // processing the event
            if !source.is_null() {
                let source: *mut ffi::android_poll_source = mem::transmute(source);
                ((*source).process)(ANDROID_APP, source);
            }
        }
    }

    // terminating the application
    unsafe { ANDROID_APP = 0 as *mut ffi::android_app };
}

/// Writer that will redirect what is written to it to the logs.
struct ToLogWriter;

impl Writer for ToLogWriter {
    fn write_all(&mut self, buf: &[u8]) -> std::old_io::IoResult<()> {
        let message = CString::from_slice(buf).as_slice_with_nul().as_ptr();
        let tag = b"RustAndroidGlueStdouterr";
        let tag = CString::from_slice(tag).as_slice_with_nul().as_ptr();
        unsafe { ffi::__android_log_write(3, tag, message) };
        Ok(())
    }
}

/// The callback for inputs.
pub extern fn inputs_callback(_: *mut ffi::android_app, event: *const ffi::AInputEvent)
    -> libc::int32_t
{
    fn send_event(event: Event) {
        let senders = get_context().senders.lock().ok().unwrap();
        for sender in senders.iter() {
            sender.send(event);
        }
    }
    fn get_xy(event: *const ffi::AInputEvent) -> (i32, i32) {
        let x = unsafe { ffi::AMotionEvent_getX(event, 0) };
        let y = unsafe { ffi::AMotionEvent_getY(event, 0) };
        (x as i32, y as i32)
    }
    let action = unsafe { ffi::AMotionEvent_getAction(event) };
    let action_code = action & ffi::AMOTION_EVENT_ACTION_MASK;
    match action_code {
        ffi::AMOTION_EVENT_ACTION_UP
            | ffi::AMOTION_EVENT_ACTION_OUTSIDE
            | ffi::AMOTION_EVENT_ACTION_CANCEL
            | ffi::AMOTION_EVENT_ACTION_POINTER_UP =>
        {
            send_event(Event::EventUp);
        },
        ffi::AMOTION_EVENT_ACTION_DOWN
            | ffi::AMOTION_EVENT_ACTION_POINTER_DOWN =>
        {
            let (x, y) = get_xy(event);
            send_event(Event::EventMove(x, y));
            send_event(Event::EventDown);
        },
        _ => {
            let (x, y) = get_xy(event);
            send_event(Event::EventMove(x, y));
        },
    }
    0
}

/// The callback for commands.
#[doc(hidden)]
pub extern fn commands_callback(_: *mut ffi::android_app, command: libc::int32_t) {
    let context = get_context();

    match command {
        ffi::APP_CMD_INIT_WINDOW => {

        },

        ffi::APP_CMD_SAVE_STATE => {

        },

        ffi::APP_CMD_TERM_WINDOW => {

        },

        ffi::APP_CMD_GAINED_FOCUS => {

        },

        ffi::APP_CMD_LOST_FOCUS => {

        },

        _ => ()
    }
}

/// Returns the current Context.
fn get_context() -> &'static Context {
    let context = unsafe { (*ANDROID_APP).userData };
    unsafe { std::mem::transmute(context) }
}

/// Adds a sender where events will be sent to.
pub fn add_sender(sender: Sender<Event>) {
    get_context().senders.lock().ok().unwrap().push(sender);
}

/// Returns a handle to the native window.
pub unsafe fn get_native_window() -> ffi::NativeWindowType {
    if ANDROID_APP.is_null() {
        panic!("The application was not initialized from android_main");
    }

    loop {
        let value = (*ANDROID_APP).window;
        if !value.is_null() {
            return value;
        }

        // spin-locking
        std::old_io::timer::sleep(std::time::Duration::milliseconds(10));
    }
}

///
pub fn write_log(message: &str) {
    let message = message.as_bytes();
    let message = CString::from_slice(message).as_slice_with_nul().as_ptr();
    let tag = b"RustAndroidGlueStdouterr";
    let tag = CString::from_slice(tag).as_slice_with_nul().as_ptr();
    unsafe { ffi::__android_log_write(3, tag, message) };
}

pub enum AssetError {
    AssetMissing,
    EmptyBuffer,
}

pub fn load_asset(filename: &str) -> Result<Vec<u8>, AssetError> {
    struct AssetCloser {
        asset: *const ffi::Asset,
    }

    impl Drop for AssetCloser {
        fn drop(&mut self) {
            unsafe {
                ffi::AAsset_close(self.asset)
            };
        }
    }

    unsafe fn get_asset_manager() -> *const ffi::AAssetManager {
        let app = &*ANDROID_APP;
        let activity = &*app.activity;
        activity.assetManager
    }

    let filename_c_str = CString::from_slice(filename.as_bytes())
        .as_slice_with_nul().as_ptr();
    let asset = unsafe {
        ffi::AAssetManager_open(
            get_asset_manager(), filename_c_str, ffi::MODE_STREAMING)
    };
    if asset.is_null() {
        return Err(AssetError::AssetMissing);
    }
    let _asset_closer = AssetCloser{asset: asset};
    let len = unsafe {
        ffi::AAsset_getLength(asset)
    };
    let buff = unsafe {
        ffi::AAsset_getBuffer(asset)
    };
    if buff.is_null() {
        return Err(AssetError::EmptyBuffer);
    }
    let vec = unsafe {
        Vec::from_raw_buf(buff as *const u8, len as usize)
    };
    Ok(vec)
}
<|endoftext|>


<commit_before>use crate::utils::span_lint;
use rustc::hir::*;
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc::{declare_lint_pass, declare_tool_lint};
use std::f64::consts as f64;
use syntax::ast::{FloatTy, Lit, LitKind};
use syntax::symbol;

declare_clippy_lint! {
    /// **What it does:** Checks for floating point literals that approximate
    /// constants which are defined in
    /// [`std::f32::consts`](https://doc.rust-lang.org/stable/std/f32/consts/#constants)
    /// or
    /// [`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants),
    /// respectively, suggesting to use the predefined constant.
    ///
    /// **Why is this bad?** Usually, the definition in the standard library is more
    /// precise than what people come up with. If you find that your definition is
    /// actually more precise, please [file a Rust
    /// issue](https://github.com/rust-lang/rust/issues).
    ///
    /// **Known problems:** If you happen to have a value that is within 1/8192 of a
    /// known constant, but is not *and should not* be the same, this lint will
    /// report your value anyway. We have not yet noticed any false positives in
    /// code we tested clippy with (this includes servo), but YMMV.
    ///
    /// **Example:**
    /// ```rust
    /// let x = 3.14;
    /// ```
    pub APPROX_CONSTANT,
    correctness,
    "the approximate of a known float constant (in `std::fXX::consts`)"
}

// Tuples are of the form (constant, name, min_digits)
const KNOWN_CONSTS: &[(f64, &str, usize)] = &[
    (f64::E, "E", 4),
    (f64::FRAC_1_PI, "FRAC_1_PI", 4),
    (f64::FRAC_1_SQRT_2, "FRAC_1_SQRT_2", 5),
    (f64::FRAC_2_PI, "FRAC_2_PI", 5),
    (f64::FRAC_2_SQRT_PI, "FRAC_2_SQRT_PI", 5),
    (f64::FRAC_PI_2, "FRAC_PI_2", 5),
    (f64::FRAC_PI_3, "FRAC_PI_3", 5),
    (f64::FRAC_PI_4, "FRAC_PI_4", 5),
    (f64::FRAC_PI_6, "FRAC_PI_6", 5),
    (f64::FRAC_PI_8, "FRAC_PI_8", 5),
    (f64::LN_10, "LN_10", 5),
    (f64::LN_2, "LN_2", 5),
    (f64::LOG10_E, "LOG10_E", 5),
    (f64::LOG2_E, "LOG2_E", 5),
    (f64::PI, "PI", 3),
    (f64::SQRT_2, "SQRT_2", 5),
];

declare_lint_pass!(ApproxConstant => [APPROX_CONSTANT]);

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ApproxConstant {
    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
        if let ExprKind::Lit(lit) = &e.node {
            check_lit(cx, lit, e);
        }
    }
}

fn check_lit(cx: &LateContext<'_, '_>, lit: &Lit, e: &Expr) {
    match lit.node {
        LitKind::Float(s, FloatTy::F32) => check_known_consts(cx, e, s, "f32"),
        LitKind::Float(s, FloatTy::F64) => check_known_consts(cx, e, s, "f64"),
        LitKind::FloatUnsuffixed(s) => check_known_consts(cx, e, s, "f{32, 64}"),
        _ => (),
    }
}

fn check_known_consts(cx: &LateContext<'_, '_>, e: &Expr, s: symbol::Symbol, module: &str) {
    let s = s.as_str();
    if s.parse::<f64>().is_ok() {
        for &(constant, name, min_digits) in KNOWN_CONSTS {
            if is_approx_const(constant, &s, min_digits) {
                span_lint(
                    cx,
                    APPROX_CONSTANT,
                    e.span,
                    &format!(
                        "approximate value of `{}::consts::{}` found. \
                         Consider using it directly",
                        module, &name
                    ),
                );
                return;
            }
        }
    }
}

/// Returns `false` if the number of significant figures in `value` are
/// less than `min_digits`; otherwise, returns true if `value` is equal
/// to `constant`, rounded to the number of digits present in `value`.
fn is_approx_const(constant: f64, value: &str, min_digits: usize) -> bool {
    if value.len() <= min_digits {
        false
    } else {
        let round_const = format!("{:.*}", value.len() - 2, constant);

        let mut trunc_const = constant.to_string();
        if trunc_const.len() > value.len() {
            trunc_const.truncate(value.len());
        }

        (value == round_const) || (value == trunc_const)
    }
}
<commit_msg>Remove approx_constant known problems<commit_after>use crate::utils::span_lint;
use rustc::hir::*;
use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
use rustc::{declare_lint_pass, declare_tool_lint};
use std::f64::consts as f64;
use syntax::ast::{FloatTy, Lit, LitKind};
use syntax::symbol;

declare_clippy_lint! {
    /// **What it does:** Checks for floating point literals that approximate
    /// constants which are defined in
    /// [`std::f32::consts`](https://doc.rust-lang.org/stable/std/f32/consts/#constants)
    /// or
    /// [`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants),
    /// respectively, suggesting to use the predefined constant.
    ///
    /// **Why is this bad?** Usually, the definition in the standard library is more
    /// precise than what people come up with. If you find that your definition is
    /// actually more precise, please [file a Rust
    /// issue](https://github.com/rust-lang/rust/issues).
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    /// ```rust
    /// let x = 3.14;
    /// ```
    pub APPROX_CONSTANT,
    correctness,
    "the approximate of a known float constant (in `std::fXX::consts`)"
}

// Tuples are of the form (constant, name, min_digits)
const KNOWN_CONSTS: &[(f64, &str, usize)] = &[
    (f64::E, "E", 4),
    (f64::FRAC_1_PI, "FRAC_1_PI", 4),
    (f64::FRAC_1_SQRT_2, "FRAC_1_SQRT_2", 5),
    (f64::FRAC_2_PI, "FRAC_2_PI", 5),
    (f64::FRAC_2_SQRT_PI, "FRAC_2_SQRT_PI", 5),
    (f64::FRAC_PI_2, "FRAC_PI_2", 5),
    (f64::FRAC_PI_3, "FRAC_PI_3", 5),
    (f64::FRAC_PI_4, "FRAC_PI_4", 5),
    (f64::FRAC_PI_6, "FRAC_PI_6", 5),
    (f64::FRAC_PI_8, "FRAC_PI_8", 5),
    (f64::LN_10, "LN_10", 5),
    (f64::LN_2, "LN_2", 5),
    (f64::LOG10_E, "LOG10_E", 5),
    (f64::LOG2_E, "LOG2_E", 5),
    (f64::PI, "PI", 3),
    (f64::SQRT_2, "SQRT_2", 5),
];

declare_lint_pass!(ApproxConstant => [APPROX_CONSTANT]);

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ApproxConstant {
    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
        if let ExprKind::Lit(lit) = &e.node {
            check_lit(cx, lit, e);
        }
    }
}

fn check_lit(cx: &LateContext<'_, '_>, lit: &Lit, e: &Expr) {
    match lit.node {
        LitKind::Float(s, FloatTy::F32) => check_known_consts(cx, e, s, "f32"),
        LitKind::Float(s, FloatTy::F64) => check_known_consts(cx, e, s, "f64"),
        LitKind::FloatUnsuffixed(s) => check_known_consts(cx, e, s, "f{32, 64}"),
        _ => (),
    }
}

fn check_known_consts(cx: &LateContext<'_, '_>, e: &Expr, s: symbol::Symbol, module: &str) {
    let s = s.as_str();
    if s.parse::<f64>().is_ok() {
        for &(constant, name, min_digits) in KNOWN_CONSTS {
            if is_approx_const(constant, &s, min_digits) {
                span_lint(
                    cx,
                    APPROX_CONSTANT,
                    e.span,
                    &format!(
                        "approximate value of `{}::consts::{}` found. \
                         Consider using it directly",
                        module, &name
                    ),
                );
                return;
            }
        }
    }
}

/// Returns `false` if the number of significant figures in `value` are
/// less than `min_digits`; otherwise, returns true if `value` is equal
/// to `constant`, rounded to the number of digits present in `value`.
fn is_approx_const(constant: f64, value: &str, min_digits: usize) -> bool {
    if value.len() <= min_digits {
        false
    } else {
        let round_const = format!("{:.*}", value.len() - 2, constant);

        let mut trunc_const = constant.to_string();
        if trunc_const.len() > value.len() {
            trunc_const.truncate(value.len());
        }

        (value == round_const) || (value == trunc_const)
    }
}
<|endoftext|>


<commit_before>use capnp;
use zmq;
use capnp_zmq;
use std;
use time;
use explorers_capnp::grid;

enum OutputMode {
    Colors,
    Confidence
}

fn write_ppm(path : &std::path::Path, grid : grid::Reader, mode : OutputMode) -> std::io::Result<()> {
    use std::io::Write;
    use std::num::Float;
    let writer = try!(std::fs::File::create(path));
    let mut buffered = ::std::io::BufWriter::new(writer);
    try!(buffered.write_all(b"P6\n"));

    let cells = grid.get_cells().unwrap();
    let width = cells.len();
    assert!(width > 0);
    let height = cells.get(0).unwrap().len();

    try!(buffered.write(format!("{} {}\n", width, height).as_bytes()));
    try!(buffered.write(b"255\n"));

    for x in 0..width {
        assert!(cells.get(x).unwrap().len() == height);
    }

    // Urgh. The cells are stored as columns, but ppm format wants the pixels in row-major order. So
    // we end up dereferencing pointers more than we'd like here. This is why We see the traversal
    // limit to the maximum in the main loop.
    for y in 0..height {
        for x in 0..width {
            let cell = cells.get(x).unwrap().get(y);

            match mode {
                OutputMode::Colors => {
                    try!(buffered.write_all(&[(cell.get_mean_red()).floor() as u8]));
                    try!(buffered.write_all(&[cell.get_mean_green().floor() as u8]));
                    try!(buffered.write_all(&[cell.get_mean_blue().floor() as u8]));
                }
                OutputMode::Confidence => {
                    let mut age = time::now().to_timespec().sec - cell.get_latest_timestamp();
                    if age < 0 { age = 0 };
                    age *= 25;
                    if age > 255 { age = 255 };
                    age = 255 - age;

                    let mut n = cell.get_number_of_updates();
                    n *= 10;
                    if n > 255 { n = 255 };

                    try!(buffered.write_all(&[0]));

                    try!(buffered.write_all(&[n as u8]));

                    try!(buffered.write_all(&[age as u8]));
                }
            }
        }
    }
    try!(buffered.flush());
    Ok(())
}

pub fn main() -> Result<(), zmq::Error> {
    use capnp::message::MessageReader;

    let mut context = zmq::Context::new();
    let mut requester = try!(context.socket(zmq::REQ));

    try!(requester.connect("tcp://localhost:5556"));

    let mut c : u32 = 0;

    loop {
        try!(requester.send(&[], 0));

        let frames = try!(capnp_zmq::recv(&mut requester));
        let segments = capnp_zmq::frames_to_segments(&frames);
        let reader = capnp::message::SegmentArrayMessageReader::new(
            &segments,
            *capnp::message::ReaderOptions::new().traversal_limit_in_words(0xffffffffffffffff));

        let grid = reader.get_root::<grid::Reader>().unwrap();

        println!("timestamp: {}", grid.get_latest_timestamp());
        println!("word count: {}", grid.total_size().unwrap().word_count);

        write_ppm(&std::path::Path::new(&format!("colors{:05}.ppm", c)),
                  grid, OutputMode::Colors).unwrap();

        write_ppm(&std::path::Path::new(&format!("conf{:05}.ppm", c)),
                  grid, OutputMode::Confidence).unwrap();

        c += 1;

        // Sleep for five seconds.
        unsafe { ::libc::funcs::posix88::unistd::sleep(5); }
    }
}
<commit_msg>console message about written files<commit_after>use capnp;
use zmq;
use capnp_zmq;
use std;
use time;
use explorers_capnp::grid;

enum OutputMode {
    Colors,
    Confidence
}

fn write_ppm(path : &std::path::Path, grid : grid::Reader, mode : OutputMode) -> std::io::Result<()> {
    use std::io::Write;
    use std::num::Float;
    println!("writing to file: {:?}", path);
    let writer = try!(std::fs::File::create(path));
    let mut buffered = ::std::io::BufWriter::new(writer);
    try!(buffered.write_all(b"P6\n"));

    let cells = grid.get_cells().unwrap();
    let width = cells.len();
    assert!(width > 0);
    let height = cells.get(0).unwrap().len();

    try!(buffered.write(format!("{} {}\n", width, height).as_bytes()));
    try!(buffered.write(b"255\n"));

    for x in 0..width {
        assert!(cells.get(x).unwrap().len() == height);
    }

    // Urgh. The cells are stored as columns, but ppm format wants the pixels in row-major order. So
    // we end up dereferencing pointers more than we'd like here. This is why We see the traversal
    // limit to the maximum in the main loop.
    for y in 0..height {
        for x in 0..width {
            let cell = cells.get(x).unwrap().get(y);

            match mode {
                OutputMode::Colors => {
                    try!(buffered.write_all(&[(cell.get_mean_red()).floor() as u8]));
                    try!(buffered.write_all(&[cell.get_mean_green().floor() as u8]));
                    try!(buffered.write_all(&[cell.get_mean_blue().floor() as u8]));
                }
                OutputMode::Confidence => {
                    let mut age = time::now().to_timespec().sec - cell.get_latest_timestamp();
                    if age < 0 { age = 0 };
                    age *= 25;
                    if age > 255 { age = 255 };
                    age = 255 - age;

                    let mut n = cell.get_number_of_updates();
                    n *= 10;
                    if n > 255 { n = 255 };

                    try!(buffered.write_all(&[0]));

                    try!(buffered.write_all(&[n as u8]));

                    try!(buffered.write_all(&[age as u8]));
                }
            }
        }
    }
    try!(buffered.flush());
    Ok(())
}

pub fn main() -> Result<(), zmq::Error> {
    use capnp::message::MessageReader;

    let mut context = zmq::Context::new();
    let mut requester = try!(context.socket(zmq::REQ));

    try!(requester.connect("tcp://localhost:5556"));

    let mut c : u32 = 0;

    loop {
        try!(requester.send(&[], 0));

        let frames = try!(capnp_zmq::recv(&mut requester));
        let segments = capnp_zmq::frames_to_segments(&frames);
        let reader = capnp::message::SegmentArrayMessageReader::new(
            &segments,
            *capnp::message::ReaderOptions::new().traversal_limit_in_words(0xffffffffffffffff));

        let grid = reader.get_root::<grid::Reader>().unwrap();

        println!("timestamp: {}", grid.get_latest_timestamp());
        println!("word count: {}", grid.total_size().unwrap().word_count);

        write_ppm(&std::path::Path::new(&format!("colors{:05}.ppm", c)),
                  grid, OutputMode::Colors).unwrap();

        write_ppm(&std::path::Path::new(&format!("conf{:05}.ppm", c)),
                  grid, OutputMode::Confidence).unwrap();

        c += 1;

        // Sleep for five seconds.
        unsafe { ::libc::funcs::posix88::unistd::sleep(5); }
    }
}
<|endoftext|>


<commit_before>
use tensor::{Tensor, TensorKind, NumLimits};

pub fn byte_tensor_kind<T>(arg: T) -> TensorKind {
    unimplemented!()
}
pub fn float_tensor_kind<T>(arg: T) -> TensorKind {
    unimplemented!()
}
pub fn long_tensor_kind<T>(arg: T) -> TensorKind {
    unimplemented!()
}
pub fn byte_tensor<T>(arg: T) -> Tensor<u8> {
    unimplemented!()
}
pub fn float_tensor<T>(arg: T) -> Tensor<f32> {
    unimplemented!()
}
pub fn double_tensor<T>(arg: T) -> Tensor<f64> {
    unimplemented!()
}
pub fn long_tensor<T>(arg: T) -> Tensor<i64> {
    unimplemented!()
}
pub fn tensor<S, D>(arg: S) -> Tensor<D> where D: NumLimits<D>{
    unimplemented!()
}
<commit_msg>give specific types<commit_after>use tensor::{Tensor, TensorKind, NumLimits};

pub fn byte_tensor_kind<u8>(arg: u8) -> TensorKind {
    unimplemented!()
}
pub fn byte_tensor_kind<T>(arg: T) -> TensorKind where T: AsRef<Vec<u8>> {
	unimplemented!()
}
pub fn byte_tensor_kind<T>(arg: T) -> TensorKind where T: AsRef<Vec<Vec<u8>>> {
    unimplemented!()
}

pub fn float_tensor_kind<T>(arg: T) -> TensorKind {
    unimplemented!()
}
pub fn long_tensor_kind<T>(arg: T) -> TensorKind {
    unimplemented!()
}
pub fn byte_tensor<T>(arg: T) -> Tensor<u8> {
    unimplemented!()
}
pub fn float_tensor<T>(arg: T) -> Tensor<f32> {
    unimplemented!()
}
pub fn double_tensor<T>(arg: T) -> Tensor<f64> {
    unimplemented!()
}
pub fn long_tensor<T>(arg: T) -> Tensor<i64>  where T: AsRef<Vec<i64>> {
	unimplemented!()
}
pub fn tensor<S, f32>(arg: S) -> Tensor<f32> where S: AsRef<Vec<Tensor<f32>>>, f32: ::tensor::tensor::NumLimits {
    unimplemented!()
}
<|endoftext|>