<commit_before>// Copyright 2013 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 to_str::{ToStr,ToStrConsume};
use str;
use cast;

/// Datatype to hold one ascii character. It is 8 bit long.
#[deriving(Clone, Eq)]
pub struct Ascii { priv chr: u8 }

pub impl Ascii {
    /// Converts a ascii character into a `u8`.
    #[inline(always)]
    fn to_byte(self) -> u8 {
        self.chr
    }

    /// Converts a ascii character into a `char`.
    #[inline(always)]
    fn to_char(self) -> char {
        self.chr as char
    }

    /// Convert to lowercase.
    #[inline(always)]
    fn to_lower(self) -> Ascii {
        if self.chr >= 65 && self.chr <= 90 {
            Ascii{chr: self.chr | 0x20 }
        } else {
            self
        }
    }

    /// Convert to uppercase.
    #[inline(always)]
    fn to_upper(self) -> Ascii {
        if self.chr >= 97 && self.chr <= 122 {
            Ascii{chr: self.chr & !0x20 }
        } else {
            self
        }
    }

    // Compares two ascii characters of equality, ignoring case.
    #[inline(always)]
    fn eq_ignore_case(self, other: Ascii) -> bool {
        self.to_lower().chr == other.to_lower().chr
    }
}

impl ToStr for Ascii {
    #[inline(always)]
    fn to_str(&self) -> ~str { str::from_bytes(['\'' as u8, self.chr, '\'' as u8]) }
}

/// Trait for converting into an ascii type.
pub trait AsciiCast<T> {
    /// Convert to an ascii type
    fn to_ascii(&self) -> T;

    /// Check if convertible to ascii
    fn is_ascii(&self) -> bool;
}

impl<'self> AsciiCast<&'self[Ascii]> for &'self [u8] {
    #[inline(always)]
    fn to_ascii(&self) -> &'self[Ascii] {
        assert!(self.is_ascii());
        unsafe{ cast::transmute(*self) }
    }

    #[inline(always)]
    fn is_ascii(&self) -> bool {
        for self.each |b| {
            if !b.is_ascii() { return false; }
        }
        true
    }
}

impl<'self> AsciiCast<&'self[Ascii]> for &'self str {
    #[inline(always)]
    fn to_ascii(&self) -> &'self[Ascii] {
        assert!(self.is_ascii());
        let (p,len): (*u8, uint) = unsafe{ cast::transmute(*self) };
        unsafe{ cast::transmute((p, len - 1))}
    }

    #[inline(always)]
    fn is_ascii(&self) -> bool {
        for self.each |b| {
            if !b.is_ascii() { return false; }
        }
        true
    }
}

impl AsciiCast<Ascii> for u8 {
    #[inline(always)]
    fn to_ascii(&self) -> Ascii {
        assert!(self.is_ascii());
        Ascii{ chr: *self }
    }

    #[inline(always)]
    fn is_ascii(&self) -> bool {
        *self & 128 == 0u8
    }
}

impl AsciiCast<Ascii> for char {
    #[inline(always)]
    fn to_ascii(&self) -> Ascii {
        assert!(self.is_ascii());
        Ascii{ chr: *self as u8 }
    }

    #[inline(always)]
    fn is_ascii(&self) -> bool {
        *self - ('\x7F' & *self) == '\x00'
    }
}

/// Trait for copyless casting to an ascii vector.
pub trait OwnedAsciiCast {
    /// Take ownership and cast to an ascii vector without trailing zero element.
    fn to_ascii_consume(self) -> ~[Ascii];
}

impl OwnedAsciiCast for ~[u8] {
    #[inline(always)]
    fn to_ascii_consume(self) -> ~[Ascii] {
        assert!(self.is_ascii());
        unsafe {cast::transmute(self)}
    }
}

impl OwnedAsciiCast for ~str {
    #[inline(always)]
    fn to_ascii_consume(self) -> ~[Ascii] {
        assert!(self.is_ascii());
        let mut s = self;
        unsafe {
            str::raw::pop_byte(&mut s);
            cast::transmute(s)
        }
    }
}

/// Trait for converting an ascii type to a string. Needed to convert `&[Ascii]` to `~str`
pub trait AsciiStr {
    /// Convert to a string.
    fn to_str_ascii(&self) -> ~str;

    /// Convert to vector representing a lower cased ascii string.
    fn to_lower(&self) -> ~[Ascii];

    /// Convert to vector representing a upper cased ascii string.
    fn to_upper(&self) -> ~[Ascii];

}

impl<'self> AsciiStr for &'self [Ascii] {
    #[inline(always)]
    fn to_str_ascii(&self) -> ~str {
        let mut cpy = self.to_owned();
        cpy.push(0u8.to_ascii());
        unsafe {cast::transmute(cpy)}
    }

    #[inline(always)]
    fn to_lower(&self) -> ~[Ascii] {
        self.map(|a| a.to_lower())
    }

    #[inline(always)]
    fn to_upper(&self) -> ~[Ascii] {
        self.map(|a| a.to_upper())
    }
}

impl ToStrConsume for ~[Ascii] {
    #[inline(always)]
    fn to_str_consume(self) -> ~str {
        let mut cpy = self;
        cpy.push(0u8.to_ascii());
        unsafe {cast::transmute(cpy)}
    }
}

mod tests {
    use super::*;

    macro_rules! v2ascii (
        ( [$($e:expr),*]) => ( [$(Ascii{chr:$e}),*]);
        (~[$($e:expr),*]) => (~[$(Ascii{chr:$e}),*]);
    )

    #[test]
    fn test_ascii() {
        assert_eq!(65u8.to_ascii().to_byte(), 65u8);
        assert_eq!(65u8.to_ascii().to_char(), 'A');
        assert_eq!('A'.to_ascii().to_char(), 'A');
        assert_eq!('A'.to_ascii().to_byte(), 65u8);

        assert_eq!('A'.to_ascii().to_lower().to_char(), 'a');
        assert_eq!('Z'.to_ascii().to_lower().to_char(), 'z');
        assert_eq!('a'.to_ascii().to_upper().to_char(), 'A');
        assert_eq!('z'.to_ascii().to_upper().to_char(), 'Z');

        assert_eq!('@'.to_ascii().to_lower().to_char(), '@');
        assert_eq!('['.to_ascii().to_lower().to_char(), '[');
        assert_eq!('`'.to_ascii().to_upper().to_char(), '`');
        assert_eq!('{'.to_ascii().to_upper().to_char(), '{');
    }

    #[test]
    fn test_ascii_vec() {
        assert_eq!((&[40u8, 32u8, 59u8]).to_ascii(), v2ascii!([40, 32, 59]));
        assert_eq!("( ;".to_ascii(),                 v2ascii!([40, 32, 59]));
        // FIXME: #5475 borrowchk error, owned vectors do not live long enough
        // if chained-from directly
        let v = ~[40u8, 32u8, 59u8]; assert_eq!(v.to_ascii(), v2ascii!([40, 32, 59]));
        let v = ~"( ;";              assert_eq!(v.to_ascii(), v2ascii!([40, 32, 59]));

        assert_eq!("abCDef&?#".to_ascii().to_lower().to_str_ascii(), ~"abcdef&?#");
        assert_eq!("abCDef&?#".to_ascii().to_upper().to_str_ascii(), ~"ABCDEF&?#");
    }

    #[test]
    fn test_owned_ascii_vec() {
        // FIXME: #4318 Compiler crashes on moving self
        //assert_eq!(~"( ;".to_ascii_consume(), v2ascii!(~[40, 32, 59]));
        //assert_eq!(~[40u8, 32u8, 59u8].to_ascii_consume(), v2ascii!(~[40, 32, 59]));
        //assert_eq!(~"( ;".to_ascii_consume_with_null(), v2ascii!(~[40, 32, 59, 0]));
        //assert_eq!(~[40u8, 32u8, 59u8].to_ascii_consume_with_null(),
        //           v2ascii!(~[40, 32, 59, 0]));
    }

    #[test]
    fn test_ascii_to_str() { assert_eq!(v2ascii!([40, 32, 59]).to_str_ascii(), ~"( ;"); }

    #[test]
    fn test_ascii_to_str_consume() {
        // FIXME: #4318 Compiler crashes on moving self
        //assert_eq!(v2ascii!(~[40, 32, 59]).to_str_consume(), ~"( ;");
    }

    #[test] #[should_fail]
    fn test_ascii_vec_fail_u8_slice()  { (&[127u8, 128u8, 255u8]).to_ascii(); }

    #[test] #[should_fail]
    fn test_ascii_vec_fail_str_slice() { "zoä华".to_ascii(); }

    #[test] #[should_fail]
    fn test_ascii_fail_u8_slice() { 255u8.to_ascii(); }

    #[test] #[should_fail]
    fn test_ascii_fail_char_slice() { 'λ'.to_ascii(); }
}
<commit_msg>Fixing some various warnings about unused imports<commit_after>// Copyright 2013 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 to_str::{ToStr,ToStrConsume};
use str;
use cast;

/// Datatype to hold one ascii character. It is 8 bit long.
#[deriving(Clone, Eq)]
pub struct Ascii { priv chr: u8 }

pub impl Ascii {
    /// Converts a ascii character into a `u8`.
    #[inline(always)]
    fn to_byte(self) -> u8 {
        self.chr
    }

    /// Converts a ascii character into a `char`.
    #[inline(always)]
    fn to_char(self) -> char {
        self.chr as char
    }

    /// Convert to lowercase.
    #[inline(always)]
    fn to_lower(self) -> Ascii {
        if self.chr >= 65 && self.chr <= 90 {
            Ascii{chr: self.chr | 0x20 }
        } else {
            self
        }
    }

    /// Convert to uppercase.
    #[inline(always)]
    fn to_upper(self) -> Ascii {
        if self.chr >= 97 && self.chr <= 122 {
            Ascii{chr: self.chr & !0x20 }
        } else {
            self
        }
    }

    // Compares two ascii characters of equality, ignoring case.
    #[inline(always)]
    fn eq_ignore_case(self, other: Ascii) -> bool {
        self.to_lower().chr == other.to_lower().chr
    }
}

impl ToStr for Ascii {
    #[inline(always)]
    fn to_str(&self) -> ~str { str::from_bytes(['\'' as u8, self.chr, '\'' as u8]) }
}

/// Trait for converting into an ascii type.
pub trait AsciiCast<T> {
    /// Convert to an ascii type
    fn to_ascii(&self) -> T;

    /// Check if convertible to ascii
    fn is_ascii(&self) -> bool;
}

impl<'self> AsciiCast<&'self[Ascii]> for &'self [u8] {
    #[inline(always)]
    fn to_ascii(&self) -> &'self[Ascii] {
        assert!(self.is_ascii());
        unsafe{ cast::transmute(*self) }
    }

    #[inline(always)]
    fn is_ascii(&self) -> bool {
        for self.each |b| {
            if !b.is_ascii() { return false; }
        }
        true
    }
}

impl<'self> AsciiCast<&'self[Ascii]> for &'self str {
    #[inline(always)]
    fn to_ascii(&self) -> &'self[Ascii] {
        assert!(self.is_ascii());
        let (p,len): (*u8, uint) = unsafe{ cast::transmute(*self) };
        unsafe{ cast::transmute((p, len - 1))}
    }

    #[inline(always)]
    fn is_ascii(&self) -> bool {
        for self.each |b| {
            if !b.is_ascii() { return false; }
        }
        true
    }
}

impl AsciiCast<Ascii> for u8 {
    #[inline(always)]
    fn to_ascii(&self) -> Ascii {
        assert!(self.is_ascii());
        Ascii{ chr: *self }
    }

    #[inline(always)]
    fn is_ascii(&self) -> bool {
        *self & 128 == 0u8
    }
}

impl AsciiCast<Ascii> for char {
    #[inline(always)]
    fn to_ascii(&self) -> Ascii {
        assert!(self.is_ascii());
        Ascii{ chr: *self as u8 }
    }

    #[inline(always)]
    fn is_ascii(&self) -> bool {
        *self - ('\x7F' & *self) == '\x00'
    }
}

/// Trait for copyless casting to an ascii vector.
pub trait OwnedAsciiCast {
    /// Take ownership and cast to an ascii vector without trailing zero element.
    fn to_ascii_consume(self) -> ~[Ascii];
}

impl OwnedAsciiCast for ~[u8] {
    #[inline(always)]
    fn to_ascii_consume(self) -> ~[Ascii] {
        assert!(self.is_ascii());
        unsafe {cast::transmute(self)}
    }
}

impl OwnedAsciiCast for ~str {
    #[inline(always)]
    fn to_ascii_consume(self) -> ~[Ascii] {
        assert!(self.is_ascii());
        let mut s = self;
        unsafe {
            str::raw::pop_byte(&mut s);
            cast::transmute(s)
        }
    }
}

/// Trait for converting an ascii type to a string. Needed to convert `&[Ascii]` to `~str`
pub trait AsciiStr {
    /// Convert to a string.
    fn to_str_ascii(&self) -> ~str;

    /// Convert to vector representing a lower cased ascii string.
    fn to_lower(&self) -> ~[Ascii];

    /// Convert to vector representing a upper cased ascii string.
    fn to_upper(&self) -> ~[Ascii];

}

impl<'self> AsciiStr for &'self [Ascii] {
    #[inline(always)]
    fn to_str_ascii(&self) -> ~str {
        let mut cpy = self.to_owned();
        cpy.push(0u8.to_ascii());
        unsafe {cast::transmute(cpy)}
    }

    #[inline(always)]
    fn to_lower(&self) -> ~[Ascii] {
        self.map(|a| a.to_lower())
    }

    #[inline(always)]
    fn to_upper(&self) -> ~[Ascii] {
        self.map(|a| a.to_upper())
    }
}

impl ToStrConsume for ~[Ascii] {
    #[inline(always)]
    fn to_str_consume(self) -> ~str {
        let mut cpy = self;
        cpy.push(0u8.to_ascii());
        unsafe {cast::transmute(cpy)}
    }
}

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

    macro_rules! v2ascii (
        ( [$($e:expr),*]) => ( [$(Ascii{chr:$e}),*]);
        (~[$($e:expr),*]) => (~[$(Ascii{chr:$e}),*]);
    )

    #[test]
    fn test_ascii() {
        assert_eq!(65u8.to_ascii().to_byte(), 65u8);
        assert_eq!(65u8.to_ascii().to_char(), 'A');
        assert_eq!('A'.to_ascii().to_char(), 'A');
        assert_eq!('A'.to_ascii().to_byte(), 65u8);

        assert_eq!('A'.to_ascii().to_lower().to_char(), 'a');
        assert_eq!('Z'.to_ascii().to_lower().to_char(), 'z');
        assert_eq!('a'.to_ascii().to_upper().to_char(), 'A');
        assert_eq!('z'.to_ascii().to_upper().to_char(), 'Z');

        assert_eq!('@'.to_ascii().to_lower().to_char(), '@');
        assert_eq!('['.to_ascii().to_lower().to_char(), '[');
        assert_eq!('`'.to_ascii().to_upper().to_char(), '`');
        assert_eq!('{'.to_ascii().to_upper().to_char(), '{');
    }

    #[test]
    fn test_ascii_vec() {
        assert_eq!((&[40u8, 32u8, 59u8]).to_ascii(), v2ascii!([40, 32, 59]));
        assert_eq!("( ;".to_ascii(),                 v2ascii!([40, 32, 59]));
        // FIXME: #5475 borrowchk error, owned vectors do not live long enough
        // if chained-from directly
        let v = ~[40u8, 32u8, 59u8]; assert_eq!(v.to_ascii(), v2ascii!([40, 32, 59]));
        let v = ~"( ;";              assert_eq!(v.to_ascii(), v2ascii!([40, 32, 59]));

        assert_eq!("abCDef&?#".to_ascii().to_lower().to_str_ascii(), ~"abcdef&?#");
        assert_eq!("abCDef&?#".to_ascii().to_upper().to_str_ascii(), ~"ABCDEF&?#");
    }

    #[test]
    fn test_owned_ascii_vec() {
        // FIXME: #4318 Compiler crashes on moving self
        //assert_eq!(~"( ;".to_ascii_consume(), v2ascii!(~[40, 32, 59]));
        //assert_eq!(~[40u8, 32u8, 59u8].to_ascii_consume(), v2ascii!(~[40, 32, 59]));
        //assert_eq!(~"( ;".to_ascii_consume_with_null(), v2ascii!(~[40, 32, 59, 0]));
        //assert_eq!(~[40u8, 32u8, 59u8].to_ascii_consume_with_null(),
        //           v2ascii!(~[40, 32, 59, 0]));
    }

    #[test]
    fn test_ascii_to_str() { assert_eq!(v2ascii!([40, 32, 59]).to_str_ascii(), ~"( ;"); }

    #[test]
    fn test_ascii_to_str_consume() {
        // FIXME: #4318 Compiler crashes on moving self
        //assert_eq!(v2ascii!(~[40, 32, 59]).to_str_consume(), ~"( ;");
    }

    #[test] #[should_fail]
    fn test_ascii_vec_fail_u8_slice()  { (&[127u8, 128u8, 255u8]).to_ascii(); }

    #[test] #[should_fail]
    fn test_ascii_vec_fail_str_slice() { "zoä华".to_ascii(); }

    #[test] #[should_fail]
    fn test_ascii_fail_u8_slice() { 255u8.to_ascii(); }

    #[test] #[should_fail]
    fn test_ascii_fail_char_slice() { 'λ'.to_ascii(); }
}
<|endoftext|>


<commit_before>// 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(not(stage1))]
#[phase(syntax)]
extern crate regex_macros;

// Dirty hack: During stage1, test dynamic regexs. For stage2, we test
// native regexs.
#[cfg(stage1)]
macro_rules! regex(
    ($re:expr) => (
        match ::regex::Regex::new($re) {
            Ok(re) => re,
            Err(err) => fail!("{}", err),
        }
    );
)

mod bench;
mod tests;

<commit_msg>Tests for dynamic regexes will now run during 'check-stage2'.<commit_after>// 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(not(stage1))]
#[phase(syntax)]
extern crate regex_macros;

#[cfg(not(stage1))]
#[path = "bench.rs"]
mod native_bench;

#[cfg(not(stage1))]
#[path = "tests.rs"]
mod native_tests;

// Due to macro scoping rules, this definition only applies for the modules
// defined below. Effectively, it allows us to use the same tests for both
// native and dynamic regexes.
macro_rules! regex(
    ($re:expr) => (
        match ::regex::Regex::new($re) {
            Ok(re) => re,
            Err(err) => fail!("{}", err),
        }
    );
)

#[path = "bench.rs"]
mod dynamic_bench;
#[path = "tests.rs"]
mod dynamic_tests;

<|endoftext|>


<commit_before>use crate::ty::subst::{SubstsRef, GenericArgKind};
use crate::ty::{self, Ty, TypeFlags, InferConst};
use crate::mir::interpret::ConstValue;

#[derive(Debug)]
pub struct FlagComputation {
    pub flags: TypeFlags,

    // see `TyS::outer_exclusive_binder` for details
    pub outer_exclusive_binder: ty::DebruijnIndex,
}

impl FlagComputation {
    fn new() -> FlagComputation {
        FlagComputation {
            flags: TypeFlags::empty(),
            outer_exclusive_binder: ty::INNERMOST,
        }
    }

    #[allow(rustc::usage_of_ty_tykind)]
    pub fn for_kind(kind: &ty::TyKind<'_>) -> FlagComputation {
        let mut result = FlagComputation::new();
        result.add_kind(kind);
        result
    }

    pub fn for_const(c: &ty::Const<'_>) -> TypeFlags {
        let mut result = FlagComputation::new();
        result.add_const(c);
        result.flags
    }

    fn add_flags(&mut self, flags: TypeFlags) {
        self.flags = self.flags | (flags & TypeFlags::NOMINAL_FLAGS);
    }

    /// indicates that `self` refers to something at binding level `binder`
    fn add_binder(&mut self, binder: ty::DebruijnIndex) {
        let exclusive_binder = binder.shifted_in(1);
        self.add_exclusive_binder(exclusive_binder);
    }

    /// indicates that `self` refers to something *inside* binding
    /// level `binder` -- not bound by `binder`, but bound by the next
    /// binder internal to it
    fn add_exclusive_binder(&mut self, exclusive_binder: ty::DebruijnIndex) {
        self.outer_exclusive_binder = self.outer_exclusive_binder.max(exclusive_binder);
    }

    /// Adds the flags/depth from a set of types that appear within the current type, but within a
    /// region binder.
    fn add_bound_computation(&mut self, computation: &FlagComputation) {
        self.add_flags(computation.flags);

        // The types that contributed to `computation` occurred within
        // a region binder, so subtract one from the region depth
        // within when adding the depth to `self`.
        let outer_exclusive_binder = computation.outer_exclusive_binder;
        if outer_exclusive_binder > ty::INNERMOST {
            self.add_exclusive_binder(outer_exclusive_binder.shifted_out(1));
        } // otherwise, this binder captures nothing
    }

    #[allow(rustc::usage_of_ty_tykind)]
    fn add_kind(&mut self, kind: &ty::TyKind<'_>) {
        match kind {
            &ty::Bool |
            &ty::Char |
            &ty::Int(_) |
            &ty::Float(_) |
            &ty::Uint(_) |
            &ty::Never |
            &ty::Str |
            &ty::Foreign(..) => {
            }

            // You might think that we could just return Error for
            // any type containing Error as a component, and get
            // rid of the TypeFlags::HAS_TY_ERR flag -- likewise for ty_bot (with
            // the exception of function types that return bot).
            // But doing so caused sporadic memory corruption, and
            // neither I (tjc) nor nmatsakis could figure out why,
            // so we're doing it this way.
            &ty::Error => {
                self.add_flags(TypeFlags::HAS_TY_ERR)
            }

            &ty::Param(_) => {
                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
                self.add_flags(TypeFlags::HAS_PARAMS);
            }

            &ty::Generator(_, ref substs, _) => {
                self.add_flags(TypeFlags::HAS_TY_CLOSURE);
                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
                self.add_substs(substs);
            }

            &ty::GeneratorWitness(ref ts) => {
                let mut computation = FlagComputation::new();
                computation.add_tys(&ts.skip_binder()[..]);
                self.add_bound_computation(&computation);
            }

            &ty::Closure(_, ref substs) => {
                self.add_flags(TypeFlags::HAS_TY_CLOSURE);
                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
                self.add_substs(substs);
            }

            &ty::Bound(debruijn, _) => {
                self.add_binder(debruijn);
            }

            &ty::Placeholder(..) => {
                self.add_flags(TypeFlags::HAS_TY_PLACEHOLDER);
            }

            &ty::Infer(infer) => {
                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES); // it might, right?
                self.add_flags(TypeFlags::HAS_TY_INFER);
                match infer {
                    ty::FreshTy(_) |
                    ty::FreshIntTy(_) |
                    ty::FreshFloatTy(_) => {
                    }

                    ty::TyVar(_) |
                    ty::IntVar(_) |
                    ty::FloatVar(_) => {
                        self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX)
                    }
                }
            }

            &ty::Adt(_, substs) => {
                self.add_substs(substs);
            }

            &ty::Projection(ref data) => {
                self.add_flags(TypeFlags::HAS_PROJECTION);
                self.add_projection_ty(data);
            }

            &ty::UnnormalizedProjection(ref data) => {
                self.add_flags(TypeFlags::HAS_PROJECTION);
                self.add_projection_ty(data);
            },

            &ty::Opaque(_, substs) => {
                self.add_flags(TypeFlags::HAS_PROJECTION);
                self.add_substs(substs);
            }

            &ty::Dynamic(ref obj, r) => {
                let mut computation = FlagComputation::new();
                for predicate in obj.skip_binder().iter() {
                    match *predicate {
                        ty::ExistentialPredicate::Trait(tr) => computation.add_substs(tr.substs),
                        ty::ExistentialPredicate::Projection(p) => {
                            let mut proj_computation = FlagComputation::new();
                            proj_computation.add_existential_projection(&p);
                            self.add_bound_computation(&proj_computation);
                        }
                        ty::ExistentialPredicate::AutoTrait(_) => {}
                    }
                }
                self.add_bound_computation(&computation);
                self.add_region(r);
            }

            &ty::Array(tt, len) => {
                self.add_ty(tt);
                self.add_const(len);
            }

            &ty::Slice(tt) => {
                self.add_ty(tt)
            }

            &ty::RawPtr(ref m) => {
                self.add_ty(m.ty);
            }

            &ty::Ref(r, ty, _) => {
                self.add_region(r);
                self.add_ty(ty);
            }

            &ty::Tuple(ref substs) => {
                self.add_substs(substs);
            }

            &ty::FnDef(_, substs) => {
                self.add_substs(substs);
            }

            &ty::FnPtr(f) => {
                self.add_fn_sig(f);
            }
        }
    }

    fn add_ty(&mut self, ty: Ty<'_>) {
        self.add_flags(ty.flags);
        self.add_exclusive_binder(ty.outer_exclusive_binder);
    }

    fn add_tys(&mut self, tys: &[Ty<'_>]) {
        for &ty in tys {
            self.add_ty(ty);
        }
    }

    fn add_fn_sig(&mut self, fn_sig: ty::PolyFnSig<'_>) {
        let mut computation = FlagComputation::new();

        computation.add_tys(fn_sig.skip_binder().inputs());
        computation.add_ty(fn_sig.skip_binder().output());

        self.add_bound_computation(&computation);
    }

    fn add_region(&mut self, r: ty::Region<'_>) {
        self.add_flags(r.type_flags());
        if let ty::ReLateBound(debruijn, _) = *r {
            self.add_binder(debruijn);
        }
    }

    fn add_const(&mut self, c: &ty::Const<'_>) {
        self.add_ty(c.ty);
        match c.val {
            ConstValue::Unevaluated(_, substs) => {
                self.add_substs(substs);
                self.add_flags(TypeFlags::HAS_PROJECTION);
            },
            ConstValue::Infer(infer) => {
                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES | TypeFlags::HAS_CT_INFER);
                match infer {
                    InferConst::Fresh(_) => {}
                    InferConst::Var(_) => self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX),
                }
            }
            ConstValue::Bound(debruijn, _) => self.add_binder(debruijn),
            ConstValue::Param(_) => {
                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES | TypeFlags::HAS_PARAMS);
            }
            ConstValue::Placeholder(_) => {
                self.add_flags(TypeFlags::HAS_FREE_REGIONS | TypeFlags::HAS_CT_PLACEHOLDER);
            }
            ConstValue::Scalar(_) => { }
            ConstValue::Slice { data: _, start: _, end: _ } => { }
            ConstValue::ByRef { alloc: _, offset: _ } => { }
        }
    }

    fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection<'_>) {
        self.add_substs(projection.substs);
        self.add_ty(projection.ty);
    }

    fn add_projection_ty(&mut self, projection_ty: &ty::ProjectionTy<'_>) {
        self.add_substs(projection_ty.substs);
    }

    fn add_substs(&mut self, substs: SubstsRef<'_>) {
        for kind in substs {
            match kind.unpack() {
                GenericArgKind::Type(ty) => self.add_ty(ty),
                GenericArgKind::Lifetime(lt) => self.add_region(lt),
                GenericArgKind::Const(ct) => self.add_const(ct),
            }
        }
    }
}
<commit_msg>Rollup merge of #65643 - varkor:remove-free-regions-from-const-placeholder, r=eddyb<commit_after>use crate::ty::subst::{SubstsRef, GenericArgKind};
use crate::ty::{self, Ty, TypeFlags, InferConst};
use crate::mir::interpret::ConstValue;

#[derive(Debug)]
pub struct FlagComputation {
    pub flags: TypeFlags,

    // see `TyS::outer_exclusive_binder` for details
    pub outer_exclusive_binder: ty::DebruijnIndex,
}

impl FlagComputation {
    fn new() -> FlagComputation {
        FlagComputation {
            flags: TypeFlags::empty(),
            outer_exclusive_binder: ty::INNERMOST,
        }
    }

    #[allow(rustc::usage_of_ty_tykind)]
    pub fn for_kind(kind: &ty::TyKind<'_>) -> FlagComputation {
        let mut result = FlagComputation::new();
        result.add_kind(kind);
        result
    }

    pub fn for_const(c: &ty::Const<'_>) -> TypeFlags {
        let mut result = FlagComputation::new();
        result.add_const(c);
        result.flags
    }

    fn add_flags(&mut self, flags: TypeFlags) {
        self.flags = self.flags | (flags & TypeFlags::NOMINAL_FLAGS);
    }

    /// indicates that `self` refers to something at binding level `binder`
    fn add_binder(&mut self, binder: ty::DebruijnIndex) {
        let exclusive_binder = binder.shifted_in(1);
        self.add_exclusive_binder(exclusive_binder);
    }

    /// indicates that `self` refers to something *inside* binding
    /// level `binder` -- not bound by `binder`, but bound by the next
    /// binder internal to it
    fn add_exclusive_binder(&mut self, exclusive_binder: ty::DebruijnIndex) {
        self.outer_exclusive_binder = self.outer_exclusive_binder.max(exclusive_binder);
    }

    /// Adds the flags/depth from a set of types that appear within the current type, but within a
    /// region binder.
    fn add_bound_computation(&mut self, computation: &FlagComputation) {
        self.add_flags(computation.flags);

        // The types that contributed to `computation` occurred within
        // a region binder, so subtract one from the region depth
        // within when adding the depth to `self`.
        let outer_exclusive_binder = computation.outer_exclusive_binder;
        if outer_exclusive_binder > ty::INNERMOST {
            self.add_exclusive_binder(outer_exclusive_binder.shifted_out(1));
        } // otherwise, this binder captures nothing
    }

    #[allow(rustc::usage_of_ty_tykind)]
    fn add_kind(&mut self, kind: &ty::TyKind<'_>) {
        match kind {
            &ty::Bool |
            &ty::Char |
            &ty::Int(_) |
            &ty::Float(_) |
            &ty::Uint(_) |
            &ty::Never |
            &ty::Str |
            &ty::Foreign(..) => {
            }

            // You might think that we could just return Error for
            // any type containing Error as a component, and get
            // rid of the TypeFlags::HAS_TY_ERR flag -- likewise for ty_bot (with
            // the exception of function types that return bot).
            // But doing so caused sporadic memory corruption, and
            // neither I (tjc) nor nmatsakis could figure out why,
            // so we're doing it this way.
            &ty::Error => {
                self.add_flags(TypeFlags::HAS_TY_ERR)
            }

            &ty::Param(_) => {
                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
                self.add_flags(TypeFlags::HAS_PARAMS);
            }

            &ty::Generator(_, ref substs, _) => {
                self.add_flags(TypeFlags::HAS_TY_CLOSURE);
                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
                self.add_substs(substs);
            }

            &ty::GeneratorWitness(ref ts) => {
                let mut computation = FlagComputation::new();
                computation.add_tys(&ts.skip_binder()[..]);
                self.add_bound_computation(&computation);
            }

            &ty::Closure(_, ref substs) => {
                self.add_flags(TypeFlags::HAS_TY_CLOSURE);
                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
                self.add_substs(substs);
            }

            &ty::Bound(debruijn, _) => {
                self.add_binder(debruijn);
            }

            &ty::Placeholder(..) => {
                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
                self.add_flags(TypeFlags::HAS_TY_PLACEHOLDER);
            }

            &ty::Infer(infer) => {
                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES); // it might, right?
                self.add_flags(TypeFlags::HAS_TY_INFER);
                match infer {
                    ty::FreshTy(_) |
                    ty::FreshIntTy(_) |
                    ty::FreshFloatTy(_) => {}

                    ty::TyVar(_) |
                    ty::IntVar(_) |
                    ty::FloatVar(_) => {
                        self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX)
                    }
                }
            }

            &ty::Adt(_, substs) => {
                self.add_substs(substs);
            }

            &ty::Projection(ref data) => {
                self.add_flags(TypeFlags::HAS_PROJECTION);
                self.add_projection_ty(data);
            }

            &ty::UnnormalizedProjection(ref data) => {
                self.add_flags(TypeFlags::HAS_PROJECTION);
                self.add_projection_ty(data);
            },

            &ty::Opaque(_, substs) => {
                self.add_flags(TypeFlags::HAS_PROJECTION);
                self.add_substs(substs);
            }

            &ty::Dynamic(ref obj, r) => {
                let mut computation = FlagComputation::new();
                for predicate in obj.skip_binder().iter() {
                    match *predicate {
                        ty::ExistentialPredicate::Trait(tr) => computation.add_substs(tr.substs),
                        ty::ExistentialPredicate::Projection(p) => {
                            let mut proj_computation = FlagComputation::new();
                            proj_computation.add_existential_projection(&p);
                            self.add_bound_computation(&proj_computation);
                        }
                        ty::ExistentialPredicate::AutoTrait(_) => {}
                    }
                }
                self.add_bound_computation(&computation);
                self.add_region(r);
            }

            &ty::Array(tt, len) => {
                self.add_ty(tt);
                self.add_const(len);
            }

            &ty::Slice(tt) => {
                self.add_ty(tt)
            }

            &ty::RawPtr(ref m) => {
                self.add_ty(m.ty);
            }

            &ty::Ref(r, ty, _) => {
                self.add_region(r);
                self.add_ty(ty);
            }

            &ty::Tuple(ref substs) => {
                self.add_substs(substs);
            }

            &ty::FnDef(_, substs) => {
                self.add_substs(substs);
            }

            &ty::FnPtr(f) => {
                self.add_fn_sig(f);
            }
        }
    }

    fn add_ty(&mut self, ty: Ty<'_>) {
        self.add_flags(ty.flags);
        self.add_exclusive_binder(ty.outer_exclusive_binder);
    }

    fn add_tys(&mut self, tys: &[Ty<'_>]) {
        for &ty in tys {
            self.add_ty(ty);
        }
    }

    fn add_fn_sig(&mut self, fn_sig: ty::PolyFnSig<'_>) {
        let mut computation = FlagComputation::new();

        computation.add_tys(fn_sig.skip_binder().inputs());
        computation.add_ty(fn_sig.skip_binder().output());

        self.add_bound_computation(&computation);
    }

    fn add_region(&mut self, r: ty::Region<'_>) {
        self.add_flags(r.type_flags());
        if let ty::ReLateBound(debruijn, _) = *r {
            self.add_binder(debruijn);
        }
    }

    fn add_const(&mut self, c: &ty::Const<'_>) {
        self.add_ty(c.ty);
        match c.val {
            ConstValue::Unevaluated(_, substs) => {
                self.add_substs(substs);
                self.add_flags(TypeFlags::HAS_PROJECTION);
            },
            ConstValue::Infer(infer) => {
                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES | TypeFlags::HAS_CT_INFER);
                match infer {
                    InferConst::Fresh(_) => {}
                    InferConst::Var(_) => self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX),
                }
            }
            ConstValue::Bound(debruijn, _) => self.add_binder(debruijn),
            ConstValue::Param(_) => {
                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
                self.add_flags(TypeFlags::HAS_PARAMS);
            }
            ConstValue::Placeholder(_) => {
                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
                self.add_flags(TypeFlags::HAS_CT_PLACEHOLDER);
            }
            ConstValue::Scalar(_) => {}
            ConstValue::Slice { .. } => {}
            ConstValue::ByRef { .. } => {}
        }
    }

    fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection<'_>) {
        self.add_substs(projection.substs);
        self.add_ty(projection.ty);
    }

    fn add_projection_ty(&mut self, projection_ty: &ty::ProjectionTy<'_>) {
        self.add_substs(projection_ty.substs);
    }

    fn add_substs(&mut self, substs: SubstsRef<'_>) {
        for kind in substs {
            match kind.unpack() {
                GenericArgKind::Type(ty) => self.add_ty(ty),
                GenericArgKind::Lifetime(lt) => self.add_region(lt),
                GenericArgKind::Const(ct) => self.add_const(ct),
            }
        }
    }
}
<|endoftext|>


<commit_before>// 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 type that can represent all platform-native strings, but is cheaply
//! interconvertable with Rust strings.
//!
//! The need for this type arises from the fact that:
//!
//! * On Unix systems, strings are often arbitrary sequences of non-zero
//!   bytes, in many cases interpreted as UTF-8.
//!
//! * On Windows, strings are often arbitrary sequences of non-zero 16-bit
//!   values, interpreted as UTF-16 when it is valid to do so.
//!
//! * In Rust, strings are always valid UTF-8, but may contain zeros.
//!
//! The types in this module bridge this gap by simultaneously representing Rust
//! and platform-native string values, and in particular allowing a Rust string
//! to be converted into an "OS" string with no cost.
//!
//! **Note**: At the moment, these types are extremely bare-bones, usable only
//! for conversion to/from various other string types. Eventually these types
//! will offer a full-fledged string API.

#![unstable(feature = "os",
            reason = "recently added as part of path/io reform")]

use core::prelude::*;

use core::borrow::{BorrowFrom, ToOwned};
use fmt::{self, Debug};
use mem;
use string::{String, CowString};
use ops;
use cmp;
use hash::{Hash, Hasher, Writer};
use old_path::{Path, GenericPath};

use sys::os_str::{Buf, Slice};
use sys_common::{AsInner, IntoInner, FromInner};
use super::AsOsStr;

/// Owned, mutable OS strings.
#[derive(Clone)]
pub struct OsString {
    inner: Buf
}

/// Slices into OS strings.
pub struct OsStr {
    inner: Slice
}

impl OsString {
    /// Constructs an `OsString` at no cost by consuming a `String`.
    pub fn from_string(s: String) -> OsString {
        OsString { inner: Buf::from_string(s) }
    }

    /// Constructs an `OsString` by copying from a `&str` slice.
    ///
    /// Equivalent to: `OsString::from_string(String::from_str(s))`.
    pub fn from_str(s: &str) -> OsString {
        OsString { inner: Buf::from_str(s) }
    }

    /// Constructs a new empty `OsString`.
    pub fn new() -> OsString {
        OsString { inner: Buf::from_string(String::new()) }
    }

    /// Convert the `OsString` into a `String` if it contains valid Unicode data.
    ///
    /// On failure, ownership of the original `OsString` is returned.
    pub fn into_string(self) -> Result<String, OsString> {
        self.inner.into_string().map_err(|buf| OsString { inner: buf} )
    }

    /// Extend the string with the given `&OsStr` slice.
    pub fn push_os_str(&mut self, s: &OsStr) {
        self.inner.push_slice(&s.inner)
    }
}

impl ops::Index<ops::RangeFull> for OsString {
    type Output = OsStr;

    #[inline]
    fn index(&self, _index: &ops::RangeFull) -> &OsStr {
        unsafe { mem::transmute(self.inner.as_slice()) }
    }
}

impl ops::Deref for OsString {
    type Target = OsStr;

    #[inline]
    fn deref(&self) -> &OsStr {
        &self[]
    }
}

impl Debug for OsString {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        fmt::Debug::fmt(&**self, formatter)
    }
}

impl PartialEq for OsString {
    fn eq(&self, other: &OsString) -> bool {
        &**self == &**other
    }
}

impl PartialEq<str> for OsString {
    fn eq(&self, other: &str) -> bool {
        &**self == other
    }
}

impl PartialEq<OsString> for str {
    fn eq(&self, other: &OsString) -> bool {
        &**other == self
    }
}

impl Eq for OsString {}

impl PartialOrd for OsString {
    #[inline]
    fn partial_cmp(&self, other: &OsString) -> Option<cmp::Ordering> {
        (&**self).partial_cmp(&**other)
    }
    #[inline]
    fn lt(&self, other: &OsString) -> bool { &**self < &**other }
    #[inline]
    fn le(&self, other: &OsString) -> bool { &**self <= &**other }
    #[inline]
    fn gt(&self, other: &OsString) -> bool { &**self > &**other }
    #[inline]
    fn ge(&self, other: &OsString) -> bool { &**self >= &**other }
}

impl PartialOrd<str> for OsString {
    #[inline]
    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
        (&**self).partial_cmp(other)
    }
}

impl Ord for OsString {
    #[inline]
    fn cmp(&self, other: &OsString) -> cmp::Ordering {
        (&**self).cmp(&**other)
    }
}

impl<'a, S: Hasher + Writer> Hash<S> for OsString {
    #[inline]
    fn hash(&self, state: &mut S) {
        (&**self).hash(state)
    }
}

impl OsStr {
    /// Coerce directly from a `&str` slice to a `&OsStr` slice.
    pub fn from_str(s: &str) -> &OsStr {
        unsafe { mem::transmute(Slice::from_str(s)) }
    }

    /// Yield a `&str` slice if the `OsStr` is valid unicode.
    ///
    /// This conversion may entail doing a check for UTF-8 validity.
    pub fn to_str(&self) -> Option<&str> {
        self.inner.to_str()
    }

    /// Convert an `OsStr` to a `CowString`.
    ///
    /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
    pub fn to_string_lossy(&self) -> CowString {
        self.inner.to_string_lossy()
    }

    /// Copy the slice into an onwed `OsString`.
    pub fn to_os_string(&self) -> OsString {
        OsString { inner: self.inner.to_owned() }
    }

    /// Get the underlying byte representation.
    ///
    /// Note: it is *crucial* that this API is private, to avoid
    /// revealing the internal, platform-specific encodings.
    fn bytes(&self) -> &[u8] {
        unsafe { mem::transmute(&self.inner) }
    }
}

impl PartialEq for OsStr {
    fn eq(&self, other: &OsStr) -> bool {
        self.bytes().eq(other.bytes())
    }
}

impl PartialEq<str> for OsStr {
    fn eq(&self, other: &str) -> bool {
        *self == *OsStr::from_str(other)
    }
}

impl PartialEq<OsStr> for str {
    fn eq(&self, other: &OsStr) -> bool {
        *other == *OsStr::from_str(self)
    }
}

impl Eq for OsStr {}

impl PartialOrd for OsStr {
    #[inline]
    fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> {
        self.bytes().partial_cmp(other.bytes())
    }
    #[inline]
    fn lt(&self, other: &OsStr) -> bool { self.bytes().lt(other.bytes()) }
    #[inline]
    fn le(&self, other: &OsStr) -> bool { self.bytes().le(other.bytes()) }
    #[inline]
    fn gt(&self, other: &OsStr) -> bool { self.bytes().gt(other.bytes()) }
    #[inline]
    fn ge(&self, other: &OsStr) -> bool { self.bytes().ge(other.bytes()) }
}

impl PartialOrd<str> for OsStr {
    #[inline]
    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
        self.partial_cmp(OsStr::from_str(other))
    }
}

// FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we
// have more flexible coherence rules.

impl Ord for OsStr {
    #[inline]
    fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) }
}

impl<'a, S: Hasher + Writer> Hash<S> for OsStr {
    #[inline]
    fn hash(&self, state: &mut S) {
        self.bytes().hash(state)
    }
}

impl Debug for OsStr {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.inner.fmt(formatter)
    }
}

impl BorrowFrom<OsString> for OsStr {
    fn borrow_from(owned: &OsString) -> &OsStr { &owned[] }
}

impl ToOwned<OsString> for OsStr {
    fn to_owned(&self) -> OsString { self.to_os_string() }
}

impl<'a, T: AsOsStr + ?Sized> AsOsStr for &'a T {
    fn as_os_str(&self) -> &OsStr {
        (*self).as_os_str()
    }
}

impl AsOsStr for OsStr {
    fn as_os_str(&self) -> &OsStr {
        self
    }
}

impl AsOsStr for OsString {
    fn as_os_str(&self) -> &OsStr {
        &self[]
    }
}

impl AsOsStr for str {
    fn as_os_str(&self) -> &OsStr {
        OsStr::from_str(self)
    }
}

impl AsOsStr for String {
    fn as_os_str(&self) -> &OsStr {
        OsStr::from_str(&self[])
    }
}

#[cfg(unix)]
impl AsOsStr for Path {
    fn as_os_str(&self) -> &OsStr {
        unsafe { mem::transmute(self.as_vec()) }
    }
}

#[cfg(windows)]
impl AsOsStr for Path {
    fn as_os_str(&self) -> &OsStr {
        // currently .as_str() is actually infallible on windows
        OsStr::from_str(self.as_str().unwrap())
    }
}

impl FromInner<Buf> for OsString {
    fn from_inner(buf: Buf) -> OsString {
        OsString { inner: buf }
    }
}

impl IntoInner<Buf> for OsString {
    fn into_inner(self) -> Buf {
        self.inner
    }
}

impl AsInner<Slice> for OsStr {
    fn as_inner(&self) -> &Slice {
        &self.inner
    }
}
<commit_msg>Rollup merge of #22328 - shepmaster:os_str_typo, r=steveklabnik<commit_after>// 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 type that can represent all platform-native strings, but is cheaply
//! interconvertable with Rust strings.
//!
//! The need for this type arises from the fact that:
//!
//! * On Unix systems, strings are often arbitrary sequences of non-zero
//!   bytes, in many cases interpreted as UTF-8.
//!
//! * On Windows, strings are often arbitrary sequences of non-zero 16-bit
//!   values, interpreted as UTF-16 when it is valid to do so.
//!
//! * In Rust, strings are always valid UTF-8, but may contain zeros.
//!
//! The types in this module bridge this gap by simultaneously representing Rust
//! and platform-native string values, and in particular allowing a Rust string
//! to be converted into an "OS" string with no cost.
//!
//! **Note**: At the moment, these types are extremely bare-bones, usable only
//! for conversion to/from various other string types. Eventually these types
//! will offer a full-fledged string API.

#![unstable(feature = "os",
            reason = "recently added as part of path/io reform")]

use core::prelude::*;

use core::borrow::{BorrowFrom, ToOwned};
use fmt::{self, Debug};
use mem;
use string::{String, CowString};
use ops;
use cmp;
use hash::{Hash, Hasher, Writer};
use old_path::{Path, GenericPath};

use sys::os_str::{Buf, Slice};
use sys_common::{AsInner, IntoInner, FromInner};
use super::AsOsStr;

/// Owned, mutable OS strings.
#[derive(Clone)]
pub struct OsString {
    inner: Buf
}

/// Slices into OS strings.
pub struct OsStr {
    inner: Slice
}

impl OsString {
    /// Constructs an `OsString` at no cost by consuming a `String`.
    pub fn from_string(s: String) -> OsString {
        OsString { inner: Buf::from_string(s) }
    }

    /// Constructs an `OsString` by copying from a `&str` slice.
    ///
    /// Equivalent to: `OsString::from_string(String::from_str(s))`.
    pub fn from_str(s: &str) -> OsString {
        OsString { inner: Buf::from_str(s) }
    }

    /// Constructs a new empty `OsString`.
    pub fn new() -> OsString {
        OsString { inner: Buf::from_string(String::new()) }
    }

    /// Convert the `OsString` into a `String` if it contains valid Unicode data.
    ///
    /// On failure, ownership of the original `OsString` is returned.
    pub fn into_string(self) -> Result<String, OsString> {
        self.inner.into_string().map_err(|buf| OsString { inner: buf} )
    }

    /// Extend the string with the given `&OsStr` slice.
    pub fn push_os_str(&mut self, s: &OsStr) {
        self.inner.push_slice(&s.inner)
    }
}

impl ops::Index<ops::RangeFull> for OsString {
    type Output = OsStr;

    #[inline]
    fn index(&self, _index: &ops::RangeFull) -> &OsStr {
        unsafe { mem::transmute(self.inner.as_slice()) }
    }
}

impl ops::Deref for OsString {
    type Target = OsStr;

    #[inline]
    fn deref(&self) -> &OsStr {
        &self[]
    }
}

impl Debug for OsString {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        fmt::Debug::fmt(&**self, formatter)
    }
}

impl PartialEq for OsString {
    fn eq(&self, other: &OsString) -> bool {
        &**self == &**other
    }
}

impl PartialEq<str> for OsString {
    fn eq(&self, other: &str) -> bool {
        &**self == other
    }
}

impl PartialEq<OsString> for str {
    fn eq(&self, other: &OsString) -> bool {
        &**other == self
    }
}

impl Eq for OsString {}

impl PartialOrd for OsString {
    #[inline]
    fn partial_cmp(&self, other: &OsString) -> Option<cmp::Ordering> {
        (&**self).partial_cmp(&**other)
    }
    #[inline]
    fn lt(&self, other: &OsString) -> bool { &**self < &**other }
    #[inline]
    fn le(&self, other: &OsString) -> bool { &**self <= &**other }
    #[inline]
    fn gt(&self, other: &OsString) -> bool { &**self > &**other }
    #[inline]
    fn ge(&self, other: &OsString) -> bool { &**self >= &**other }
}

impl PartialOrd<str> for OsString {
    #[inline]
    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
        (&**self).partial_cmp(other)
    }
}

impl Ord for OsString {
    #[inline]
    fn cmp(&self, other: &OsString) -> cmp::Ordering {
        (&**self).cmp(&**other)
    }
}

impl<'a, S: Hasher + Writer> Hash<S> for OsString {
    #[inline]
    fn hash(&self, state: &mut S) {
        (&**self).hash(state)
    }
}

impl OsStr {
    /// Coerce directly from a `&str` slice to a `&OsStr` slice.
    pub fn from_str(s: &str) -> &OsStr {
        unsafe { mem::transmute(Slice::from_str(s)) }
    }

    /// Yield a `&str` slice if the `OsStr` is valid unicode.
    ///
    /// This conversion may entail doing a check for UTF-8 validity.
    pub fn to_str(&self) -> Option<&str> {
        self.inner.to_str()
    }

    /// Convert an `OsStr` to a `CowString`.
    ///
    /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
    pub fn to_string_lossy(&self) -> CowString {
        self.inner.to_string_lossy()
    }

    /// Copy the slice into an owned `OsString`.
    pub fn to_os_string(&self) -> OsString {
        OsString { inner: self.inner.to_owned() }
    }

    /// Get the underlying byte representation.
    ///
    /// Note: it is *crucial* that this API is private, to avoid
    /// revealing the internal, platform-specific encodings.
    fn bytes(&self) -> &[u8] {
        unsafe { mem::transmute(&self.inner) }
    }
}

impl PartialEq for OsStr {
    fn eq(&self, other: &OsStr) -> bool {
        self.bytes().eq(other.bytes())
    }
}

impl PartialEq<str> for OsStr {
    fn eq(&self, other: &str) -> bool {
        *self == *OsStr::from_str(other)
    }
}

impl PartialEq<OsStr> for str {
    fn eq(&self, other: &OsStr) -> bool {
        *other == *OsStr::from_str(self)
    }
}

impl Eq for OsStr {}

impl PartialOrd for OsStr {
    #[inline]
    fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> {
        self.bytes().partial_cmp(other.bytes())
    }
    #[inline]
    fn lt(&self, other: &OsStr) -> bool { self.bytes().lt(other.bytes()) }
    #[inline]
    fn le(&self, other: &OsStr) -> bool { self.bytes().le(other.bytes()) }
    #[inline]
    fn gt(&self, other: &OsStr) -> bool { self.bytes().gt(other.bytes()) }
    #[inline]
    fn ge(&self, other: &OsStr) -> bool { self.bytes().ge(other.bytes()) }
}

impl PartialOrd<str> for OsStr {
    #[inline]
    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
        self.partial_cmp(OsStr::from_str(other))
    }
}

// FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we
// have more flexible coherence rules.

impl Ord for OsStr {
    #[inline]
    fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) }
}

impl<'a, S: Hasher + Writer> Hash<S> for OsStr {
    #[inline]
    fn hash(&self, state: &mut S) {
        self.bytes().hash(state)
    }
}

impl Debug for OsStr {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.inner.fmt(formatter)
    }
}

impl BorrowFrom<OsString> for OsStr {
    fn borrow_from(owned: &OsString) -> &OsStr { &owned[] }
}

impl ToOwned<OsString> for OsStr {
    fn to_owned(&self) -> OsString { self.to_os_string() }
}

impl<'a, T: AsOsStr + ?Sized> AsOsStr for &'a T {
    fn as_os_str(&self) -> &OsStr {
        (*self).as_os_str()
    }
}

impl AsOsStr for OsStr {
    fn as_os_str(&self) -> &OsStr {
        self
    }
}

impl AsOsStr for OsString {
    fn as_os_str(&self) -> &OsStr {
        &self[]
    }
}

impl AsOsStr for str {
    fn as_os_str(&self) -> &OsStr {
        OsStr::from_str(self)
    }
}

impl AsOsStr for String {
    fn as_os_str(&self) -> &OsStr {
        OsStr::from_str(&self[])
    }
}

#[cfg(unix)]
impl AsOsStr for Path {
    fn as_os_str(&self) -> &OsStr {
        unsafe { mem::transmute(self.as_vec()) }
    }
}

#[cfg(windows)]
impl AsOsStr for Path {
    fn as_os_str(&self) -> &OsStr {
        // currently .as_str() is actually infallible on windows
        OsStr::from_str(self.as_str().unwrap())
    }
}

impl FromInner<Buf> for OsString {
    fn from_inner(buf: Buf) -> OsString {
        OsString { inner: buf }
    }
}

impl IntoInner<Buf> for OsString {
    fn into_inner(self) -> Buf {
        self.inner
    }
}

impl AsInner<Slice> for OsStr {
    fn as_inner(&self) -> &Slice {
        &self.inner
    }
}
<|endoftext|>


<commit_before>use byteorder::{ReadBytesExt, LittleEndian};
use lnkpkg::errors::{LnkError};
use lnkpkg::utils;
use std::io::SeekFrom;
use std::io::Read;
use std::io::Seek;

#[derive(Serialize,Debug)]
pub struct VolumeInfo {
    pub vi_size: u32,
    pub drive_type: u32,
    pub serial_number: u32,
    pub offset_vol_label: u32,
    pub offset_vol_label_unicode: Option<u32>,
    pub volume_label: String,
    pub volume_label_unicode: Option<String>
}

impl VolumeInfo {
    pub fn new<Rs: Read+Seek>(mut reader: Rs) -> Result<VolumeInfo,LnkError> {
        // Get Current Pos
        let _offset = reader.seek(
            SeekFrom::Current(0)
        )?;

        let vi_size = reader.read_u32::<LittleEndian>()?;
        let drive_type = reader.read_u32::<LittleEndian>()?;
        let serial_number = reader.read_u32::<LittleEndian>()?;
        let offset_vol_label = reader.read_u32::<LittleEndian>()?;

        let mut offset_vol_label_unicode = None;
        if offset_vol_label > 16 {
            offset_vol_label_unicode = Some(reader.read_u32::<LittleEndian>()?);
        }

        // Get volume label
        reader.seek(
            SeekFrom::Start(_offset + offset_vol_label as u64)
        )?;
        let volume_label = utils::read_string_u8_till_null(&mut reader)?;

        let mut volume_label_unicode = None;
        if offset_vol_label_unicode.is_some() {
            reader.seek(
                SeekFrom::Start(_offset + offset_vol_label_unicode.unwrap() as u64)
            )?;
            volume_label_unicode = Some(utils::read_string_u16_till_null(&mut reader)?);
        }

        Ok(
            VolumeInfo {
                vi_size: vi_size,
                drive_type: drive_type,
                serial_number: serial_number,
                offset_vol_label: offset_vol_label,
                offset_vol_label_unicode: offset_vol_label_unicode,
                volume_label: volume_label,
                volume_label_unicode: volume_label_unicode
            }
        )
    }
}
<commit_msg>Added DriveType and VolumeSerialNumber structs and serialization formating for VolumeInfo struct<commit_after>use byteorder::{ReadBytesExt, LittleEndian, ByteOrder};
use serde::{ser};
use lnkpkg::errors::{LnkError};
use lnkpkg::utils;
use std::mem::transmute;
use std::fmt;
use std::fmt::{Display,Debug};
use std::io::SeekFrom;
use std::io::Read;
use std::io::Seek;

pub struct VolumeSerialNumber(pub u32);
impl VolumeSerialNumber{
    pub fn to_string(&self)->String{
        let buffer: [u8; 4] = unsafe {
            transmute(self.0.to_le())
        };

        format!(
            "{:04X}-{:04X}",
            LittleEndian::read_u16(&buffer[2..4]),
            LittleEndian::read_u16(&buffer[0..2])
        )
    }
}
impl Display for VolumeSerialNumber {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,"{}",self.to_string())
    }
}
impl Debug for VolumeSerialNumber {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,"{}",self.to_string())
    }
}
impl ser::Serialize for VolumeSerialNumber {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ser::Serializer
    {
        serializer.serialize_str(
            &self.to_string()
        )
    }
}

pub struct DriveType(pub u32);
impl DriveType{
    pub fn to_string(&self)->String{
        match self.0 {
            0 => "DRIVE_UNKNOWN".to_string(),
            1 => "DRIVE_NO_ROOT_DIR".to_string(),
            2 => "DRIVE_REMOVABLE".to_string(),
            3 => "DRIVE_FIXED".to_string(),
            4 => "DRIVE_REMOTE".to_string(),
            5 => "DRIVE_CDROM".to_string(),
            6 => "DRIVE_RAMDISK".to_string(),
            _ => format!("UNKOWN_VALUE_0x{:08X}",self.0)
        }
    }
}
impl Display for DriveType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,"{}",self.to_string())
    }
}
impl Debug for DriveType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,"{}",self.to_string())
    }
}
impl ser::Serialize for DriveType {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: ser::Serializer
    {
        serializer.serialize_str(
            &self.to_string()
        )
    }
}

#[derive(Serialize,Debug)]
pub struct VolumeInfo {
    #[serde(skip_serializing)]
    pub vi_size: u32,
    pub drive_type: DriveType,
    pub serial_number: VolumeSerialNumber,
    #[serde(skip_serializing)]
    pub offset_vol_label: u32,
    #[serde(skip_serializing)]
    pub offset_vol_label_unicode: Option<u32>,
    pub volume_label: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub volume_label_unicode: Option<String>
}

impl VolumeInfo {
    pub fn new<Rs: Read+Seek>(mut reader: Rs) -> Result<VolumeInfo,LnkError> {
        // Get Current Pos
        let _offset = reader.seek(
            SeekFrom::Current(0)
        )?;

        let vi_size = reader.read_u32::<LittleEndian>()?;
        let drive_type = DriveType(reader.read_u32::<LittleEndian>()?);
        let serial_number = VolumeSerialNumber(reader.read_u32::<LittleEndian>()?);
        let offset_vol_label = reader.read_u32::<LittleEndian>()?;

        let mut offset_vol_label_unicode = None;
        if offset_vol_label > 16 {
            offset_vol_label_unicode = Some(reader.read_u32::<LittleEndian>()?);
        }

        // Get volume label
        reader.seek(
            SeekFrom::Start(_offset + offset_vol_label as u64)
        )?;
        let volume_label = utils::read_string_u8_till_null(&mut reader)?;

        let mut volume_label_unicode = None;
        if offset_vol_label_unicode.is_some() {
            reader.seek(
                SeekFrom::Start(_offset + offset_vol_label_unicode.unwrap() as u64)
            )?;
            volume_label_unicode = Some(utils::read_string_u16_till_null(&mut reader)?);
        }

        Ok(
            VolumeInfo {
                vi_size: vi_size,
                drive_type: drive_type,
                serial_number: serial_number,
                offset_vol_label: offset_vol_label,
                offset_vol_label_unicode: offset_vol_label_unicode,
                volume_label: volume_label,
                volume_label_unicode: volume_label_unicode
            }
        )
    }
}
<|endoftext|>


<commit_before>use std::f32;
use linalg::Point;
use linalg::Vector;

/// Ray is a standard 3D ray, starting at origin `o` and heading in direction `d`
/// The min and max points along the ray can be specified with `min_t` and `max_t`
/// `depth` is the recursion depth of the ray
#[derive(Show, Copy, PartialEq)]
pub struct Ray {
    /// Origin of the ray
    pub o: Point,
    /// Direction the ray is heading
    pub d: Vector,
    /// Point along the ray that the actual ray starts at, `p = o + min_t * d`
    pub min_t: f32,
    /// Point along the ray at which it stops, will be inf if the ray is infinite
    pub max_t: f32,
    /// Recursion depth of the ray
    pub depth: i32,
}

impl Ray {
    /// Create a new ray from `o` heading in `d` with infinite length
    pub fn new(o: &Point, d: &Vector) -> Ray {
        Ray { o: *o, d: *d, min_t: 0f32, max_t: f32::INFINITY, depth: 0 }
    }
    /// Create a new segment ray from `o + min_t * d` to `o + max_t * d`
    pub fn segment(o: &Point, d: &Vector, min_t: f32, max_t: f32) -> Ray {
        Ray { o: *o, d: *d, min_t: min_t, max_t: max_t, depth: 0}
    }
    /// Create a child ray from the parent starting at `o` and heading in `d`
    pub fn child(&self, o: &Point, d: &Vector) -> Ray {
        Ray { o: *o, d: *d, min_t: 0f32, max_t: f32::INFINITY, depth: self.depth + 1 }
    }
    /// Create a child ray segment from `o + min_t * d` to `o + max_t * d`
    pub fn child_segment(&self, o: &Point, d: &Vector, min_t: f32, max_t: f32) -> Ray {
        Ray { o: *o, d: *d, min_t: min_t, max_t: max_t, depth: self.depth + 1}
    }
    /// Evaulate the ray equation at some t value and return the point
    /// returns result of `self.o + t * self.d`
    pub fn at(&self, t: f32) -> Point {
        self.o + self.d * t
    }
}

<commit_msg>Depth for rays should be an unsigned value<commit_after>use std::f32;
use linalg::Point;
use linalg::Vector;

/// Ray is a standard 3D ray, starting at origin `o` and heading in direction `d`
/// The min and max points along the ray can be specified with `min_t` and `max_t`
/// `depth` is the recursion depth of the ray
#[derive(Show, Copy, PartialEq)]
pub struct Ray {
    /// Origin of the ray
    pub o: Point,
    /// Direction the ray is heading
    pub d: Vector,
    /// Point along the ray that the actual ray starts at, `p = o + min_t * d`
    pub min_t: f32,
    /// Point along the ray at which it stops, will be inf if the ray is infinite
    pub max_t: f32,
    /// Recursion depth of the ray
    pub depth: u32,
}

impl Ray {
    /// Create a new ray from `o` heading in `d` with infinite length
    pub fn new(o: &Point, d: &Vector) -> Ray {
        Ray { o: *o, d: *d, min_t: 0f32, max_t: f32::INFINITY, depth: 0 }
    }
    /// Create a new segment ray from `o + min_t * d` to `o + max_t * d`
    pub fn segment(o: &Point, d: &Vector, min_t: f32, max_t: f32) -> Ray {
        Ray { o: *o, d: *d, min_t: min_t, max_t: max_t, depth: 0}
    }
    /// Create a child ray from the parent starting at `o` and heading in `d`
    pub fn child(&self, o: &Point, d: &Vector) -> Ray {
        Ray { o: *o, d: *d, min_t: 0f32, max_t: f32::INFINITY, depth: self.depth + 1 }
    }
    /// Create a child ray segment from `o + min_t * d` to `o + max_t * d`
    pub fn child_segment(&self, o: &Point, d: &Vector, min_t: f32, max_t: f32) -> Ray {
        Ray { o: *o, d: *d, min_t: min_t, max_t: max_t, depth: self.depth + 1}
    }
    /// Evaulate the ray equation at some t value and return the point
    /// returns result of `self.o + t * self.d`
    pub fn at(&self, t: f32) -> Point {
        self.o + self.d * t
    }
}

<|endoftext|>


<commit_before>use buckets::Buckets;
use time;
use std::net::TcpStream;
use std::io::{BufReader, BufRead, Write};
use std::fmt::Write as fmtWrite;

/// Handle the management commands
/// returning the response to send back.
pub fn exec(stream: TcpStream, buckets: &Buckets) {
    let mut reader = BufReader::new(stream);
    let mut done = false;

    while !done {
        let mut buffer = String::new();
        let _ = reader.read_line(&mut buffer);
        let command = buffer.split_whitespace()
            .next()
            .unwrap_or("")
            .to_lowercase();
        let mut writer = reader.get_mut();

        // Trigger Deref<Target = str>
        match &*command {
            "help" => {
                let mut help = String::new();
                help.push_str("Statsd Admin Console:\n");
                help.push_str("\n");
                help.push_str("Available commands:\n");
                help.push_str("stats    - print server stats.\n");
                help.push_str("counters - print counter data.\n");
                help.push_str("gauges   - print gauge data.\n");
                help.push_str("timers   - print timer data.\n");
                help.push_str("clear    - clear stored metrics.\n");
                help.push_str("quit     - close this connection.\n");
                let _ = writer.write(&help.as_bytes());
            },
            "stats" => {
                let mut out = String::new();
                let uptime = (time::get_time() - buckets.start_time()).num_seconds();
                write!(out, "uptime: {} seconds\n", uptime).unwrap();
                write!(out, "bad_messages: {}\n", buckets.bad_messages()).unwrap();
                write!(out, "total_messages: {}\n", buckets.total_messages()).unwrap();

                let _ = writer.write(&out.as_bytes());
            },
            /*
            "counters" => {
            }
            "gauges" => {
            },
            "timers" => {
            },
            */
            "quit" => {
                let bye = "Good bye!\n";
                let _ = writer.write(&bye.as_bytes());
                done = true
            }
            x => {
                let out = format!("ERROR - unknown command `{}`\n", x);
                let _ = writer.write(&out.as_bytes());
            }
        }
        let _ = writer.flush();
    }
}
<commit_msg>Implement other admin debug output commands.<commit_after>use buckets::Buckets;
use time;
use std::net::TcpStream;
use std::io::{BufReader, BufRead, Write};
use std::fmt::Write as fmtWrite;

/// Handle the management commands
/// returning the response to send back.
pub fn exec(stream: TcpStream, buckets: &Buckets) {
    let mut reader = BufReader::new(stream);
    let mut done = false;

    while !done {
        let mut buffer = String::new();
        let _ = reader.read_line(&mut buffer);
        let command = buffer.split_whitespace()
            .next()
            .unwrap_or("")
            .to_lowercase();
        let mut writer = reader.get_mut();
        let mut out = String::new();

        // Trigger Deref<Target = str>
        match &*command {
            "help" => {
                out.push_str("Statsd Admin Console:\n");
                out.push_str("\n");
                out.push_str("Available commands:\n");
                out.push_str("stats    - print server stats.\n");
                out.push_str("counters - print counter data.\n");
                out.push_str("gauges   - print gauge data.\n");
                out.push_str("timers   - print timer data.\n");
                out.push_str("clear    - clear stored metrics.\n");
                out.push_str("quit     - close this connection.\n");
            },
            "stats" => {
                let uptime = (time::get_time() - buckets.start_time()).num_seconds();
                write!(out, "uptime: {} seconds\n", uptime).unwrap();
                write!(out, "bad_messages: {}\n", buckets.bad_messages()).unwrap();
                write!(out, "total_messages: {}\n", buckets.total_messages()).unwrap();
                write!(out, "END\n\n").unwrap();
            },
            "counters" => {
                for (key, value) in buckets.counters().iter() {
                    write!(out, " {}: {}\n", key, value).unwrap();
                }
                write!(out, "END\n\n").unwrap();
            },
            "gauges" => {
                for (key, value) in buckets.gauges().iter() {
                    write!(out, " {}: {}\n", key, value).unwrap();
                }
                write!(out, "END\n\n").unwrap();
            },
            "timers" => {
                for (key, value) in buckets.timers().iter() {
                    write!(out, " {}: {:?}\n", key, value).unwrap();
                }
                write!(out, "END\n\n").unwrap();
            },
            "quit" => {
                write!(out, "Good bye!\n\n").unwrap();
                done = true
            },
            x => {
                write!(out, "ERROR - unknown command `{}`\n", x).unwrap();
            }
        }
        let _ = writer.write(&out.as_bytes());
        let _ = writer.flush();
    }
}
<|endoftext|>


<commit_before>#![crate_name = "printenv"]
#![feature(collections, core, old_io, os, rustc_private)]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

/* last synced with: printenv (GNU coreutils) 8.13 */

extern crate getopts;
extern crate libc;

use std::os;
use std::old_io::print;

#[path = "../common/util.rs"]
#[macro_use]
mod util;

static NAME: &'static str = "printenv";

pub fn uumain(args: Vec<String>) -> i32 {
    let program = args[0].clone();
    let opts = [
        getopts::optflag("0", "null", "end each output line with 0 byte rather than newline"),
        getopts::optflag("h", "help", "display this help and exit"),
        getopts::optflag("V", "version", "output version information and exit"),
    ];
    let matches = match getopts::getopts(args.tail(), &opts) {
        Ok(m) => m,
        Err(f) => {
            crash!(1, "Invalid options\n{}", f)
        }
    };
    if matches.opt_present("help") {
        println!("printenv 1.0.0");
        println!("");
        println!("Usage:");
        println!("  {0} [VARIABLE]... [OPTION]...", program);
        println!("");
        print(getopts::usage("Prints the given environment VARIABLE(s), otherwise prints them all.", &opts).as_slice());
        return 0;
    }
    if matches.opt_present("version") {
        println!("printenv 1.0.0");
        return 0;
    }
    let mut separator = "\n";
    if matches.opt_present("null") {
        separator = "\x00";
    };

    exec(matches.free, separator);

    0
}

pub fn exec(args: Vec<String>, separator: &str) {
    if args.is_empty() {
        let vars = os::env();
        for (env_var, value) in vars.into_iter() {
            print!("{0}={1}", env_var, value);
            print(separator);
        }
        return;
    }

    for env_var in args.iter() {
        match os::getenv(env_var.as_slice()) {
            Some(var) => {
                print(var.as_slice());
                print(separator);
            }
            _ => ()
        }
    }
}
<commit_msg>Fix printenv.<commit_after>#![crate_name = "printenv"]
#![feature(rustc_private)]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

/* last synced with: printenv (GNU coreutils) 8.13 */

extern crate getopts;
extern crate libc;

use std::env;
use std::io::Write;

#[path = "../common/util.rs"]
#[macro_use]
mod util;

static NAME: &'static str = "printenv";

pub fn uumain(args: Vec<String>) -> i32 {
    let program = args[0].clone();
    let opts = [
        getopts::optflag("0", "null", "end each output line with 0 byte rather than newline"),
        getopts::optflag("h", "help", "display this help and exit"),
        getopts::optflag("V", "version", "output version information and exit"),
    ];
    let matches = match getopts::getopts(&args[1..], &opts) {
        Ok(m) => m,
        Err(f) => {
            crash!(1, "Invalid options\n{}", f)
        }
    };
    if matches.opt_present("help") {
        println!("printenv 1.0.0");
        println!("");
        println!("Usage:");
        println!("  {0} [VARIABLE]... [OPTION]...", program);
        println!("");
        print!("{}", getopts::usage("Prints the given environment VARIABLE(s), otherwise prints them all.", &opts));
        return 0;
    }
    if matches.opt_present("version") {
        println!("printenv 1.0.0");
        return 0;
    }
    let mut separator = "\n";
    if matches.opt_present("null") {
        separator = "\x00";
    };

    exec(matches.free, separator);

    0
}

pub fn exec(args: Vec<String>, separator: &str) {
    if args.is_empty() {
        for (env_var, value) in env::vars() {
            print!("{}={}{}", env_var, value, separator);
        }
        return;
    }

    for env_var in args.iter() {
        match env::var(env_var) {
            Ok(var) => {
                print!("{}{}", var, separator);
            }
            _ => ()
        }
    }
}
<|endoftext|>


<commit_before>use core::mem;

use common::elf::*;

use programs::common::*;

pub struct Executor {
    executable: ELF,
    mapped: AtomicUsize,
    entry: usize,
    exit: usize,
    draw: usize,
    on_key: usize,
    on_mouse: usize
}

impl Executor {
    pub fn new() -> Executor {
        Executor {
            executable: ELF::new(),
            mapped: AtomicUsize::new(0),
            entry: 0,
            exit: 0,
            draw: 0,
            on_mouse: 0,
            on_key: 0
        }
    }

    unsafe fn entry(&mut self){
        if self.executable.can_call(self.entry){
            //Rediculous call mechanism
            self.unsafe_map();
            let fn_ptr: *const usize = &self.entry;
            (*(fn_ptr as *const fn()))();
            self.unsafe_unmap();
        }
    }

    unsafe fn unsafe_map(&mut self){
        let mapped = self.mapped.fetch_add(1, Ordering::SeqCst);
        if self.executable.data > 0 && mapped == 0{
            self.executable.map();
        }
    }

    unsafe fn unsafe_unmap(&mut self){
        let mapped = self.mapped.fetch_sub(1, Ordering::SeqCst);
        if self.executable.data > 0 && mapped == 1{
            self.executable.unmap();
        }
    }
}

impl Drop for Executor {
    fn drop(&mut self){
        unsafe{
            if self.executable.can_call(self.exit){
                //Rediculous call mechanism
                self.unsafe_map();
                let fn_ptr: *const usize = &self.exit;
                (*(fn_ptr as *const fn()))();
                self.unsafe_unmap();
            }
        }
    }
}

impl SessionItem for Executor {
    fn main(&mut self, url: URL){
        let mut resource = url.open();

        let mut vec: Vec<u8> = Vec::new();
        match resource.read_to_end(&mut vec){
            Option::Some(_) => {
                unsafe{
                    let reenable = start_no_ints();

                    self.executable = ELF::from_data(vec.as_ptr() as usize);
                    //self.executable.d();

                    self.entry = self.executable.entry();
                    self.exit = self.executable.symbol("exit".to_string());
                    self.draw = self.executable.symbol("draw".to_string());
                    self.on_key = self.executable.symbol("on_key".to_string());
                    self.on_mouse = self.executable.symbol("on_mouse".to_string());

                    self.entry();

                    RedrawEvent {
                        redraw: REDRAW_ALL
                    }.to_event().trigger();

                    end_no_ints(reenable);
                }
            },
            Option::None => ()
        }
    }

    fn draw(&self, display: &Display) -> bool{
        unsafe {
            if self.executable.can_call(self.draw){
                //Rediculous call mechanism
                let self_mut: *mut Executor = mem::transmute(self);

                (*self_mut).unsafe_map();
                let fn_ptr: *const usize = &self.draw;
                let ret = (*(fn_ptr as *const fn(&Display) -> bool))(display);
                (*self_mut).unsafe_unmap();

                return ret;
            }
        }
        return true;
    }

    fn on_key(&mut self, key_event: KeyEvent){
        unsafe {
            if self.executable.can_call(self.on_key){
                //Rediculous call mechanism
                self.unsafe_map();
                let fn_ptr: *const usize = &self.on_key;
                (*(fn_ptr as *const fn(KeyEvent)))(key_event);
                self.unsafe_unmap();
            }
        }
    }

    fn on_mouse(&mut self, mouse_event: MouseEvent, allow_catch: bool) -> bool{
        unsafe {
            if self.executable.can_call(self.on_mouse){
                //Rediculous call mechanism
                self.unsafe_map();
                let fn_ptr: *const usize = &self.on_mouse;
                let ret = (*(fn_ptr as *const fn(MouseEvent, bool) -> bool))(mouse_event, allow_catch);
                self.unsafe_unmap();
                return ret;
            }
        }
        return false;
    }
}
<commit_msg>Atomic map/unmap<commit_after>use core::mem;

use common::elf::*;

use programs::common::*;

pub struct Executor {
    executable: ELF,
    mapped: AtomicUsize,
    entry: usize,
    exit: usize,
    draw: usize,
    on_key: usize,
    on_mouse: usize
}

impl Executor {
    pub fn new() -> Executor {
        Executor {
            executable: ELF::new(),
            mapped: AtomicUsize::new(0),
            entry: 0,
            exit: 0,
            draw: 0,
            on_mouse: 0,
            on_key: 0
        }
    }

    unsafe fn entry(&mut self){
        if self.executable.can_call(self.entry){
            //Rediculous call mechanism
            self.unsafe_map();
            let fn_ptr: *const usize = &self.entry;
            (*(fn_ptr as *const fn()))();
            self.unsafe_unmap();
        }
    }

    unsafe fn unsafe_map(&mut self){
        let reenable = start_no_ints();
        let mapped = self.mapped.fetch_add(1, Ordering::SeqCst);
        if self.executable.data > 0 && mapped == 0{
            self.executable.map();
        }
        end_no_ints(reenable);
    }

    unsafe fn unsafe_unmap(&mut self){
        let reenable = start_no_ints();
        let mapped = self.mapped.fetch_sub(1, Ordering::SeqCst);
        if self.executable.data > 0 && mapped == 1{
            self.executable.unmap();
        }
        end_no_ints(reenable);
    }
}

impl Drop for Executor {
    fn drop(&mut self){
        unsafe{
            if self.executable.can_call(self.exit){
                //Rediculous call mechanism
                self.unsafe_map();
                let fn_ptr: *const usize = &self.exit;
                (*(fn_ptr as *const fn()))();
                self.unsafe_unmap();
            }
        }
    }
}

impl SessionItem for Executor {
    fn main(&mut self, url: URL){
        let mut resource = url.open();

        let mut vec: Vec<u8> = Vec::new();
        match resource.read_to_end(&mut vec){
            Option::Some(_) => {
                unsafe{
                    let reenable = start_no_ints();

                    self.executable = ELF::from_data(vec.as_ptr() as usize);
                    //self.executable.d();

                    self.entry = self.executable.entry();
                    self.exit = self.executable.symbol("exit".to_string());
                    self.draw = self.executable.symbol("draw".to_string());
                    self.on_key = self.executable.symbol("on_key".to_string());
                    self.on_mouse = self.executable.symbol("on_mouse".to_string());

                    self.entry();

                    RedrawEvent {
                        redraw: REDRAW_ALL
                    }.to_event().trigger();

                    end_no_ints(reenable);
                }
            },
            Option::None => ()
        }
    }

    fn draw(&self, display: &Display) -> bool{
        unsafe {
            if self.executable.can_call(self.draw){
                //Rediculous call mechanism
                let self_mut: *mut Executor = mem::transmute(self);

                (*self_mut).unsafe_map();
                let fn_ptr: *const usize = &self.draw;
                let ret = (*(fn_ptr as *const fn(&Display) -> bool))(display);
                (*self_mut).unsafe_unmap();

                return ret;
            }
        }
        return true;
    }

    fn on_key(&mut self, key_event: KeyEvent){
        unsafe {
            if self.executable.can_call(self.on_key){
                //Rediculous call mechanism
                self.unsafe_map();
                let fn_ptr: *const usize = &self.on_key;
                (*(fn_ptr as *const fn(KeyEvent)))(key_event);
                self.unsafe_unmap();
            }
        }
    }

    fn on_mouse(&mut self, mouse_event: MouseEvent, allow_catch: bool) -> bool{
        unsafe {
            if self.executable.can_call(self.on_mouse){
                //Rediculous call mechanism
                self.unsafe_map();
                let fn_ptr: *const usize = &self.on_mouse;
                let ret = (*(fn_ptr as *const fn(MouseEvent, bool) -> bool))(mouse_event, allow_catch);
                self.unsafe_unmap();
                return ret;
            }
        }
        return false;
    }
}
<|endoftext|>


<commit_before>use std::{mem, sync::Arc};

use bifrost::{conshash::ConsistentHashing, raft::client::RaftClient, rpc::RPCError};
use dovahkiin::{expr::serde::Expr, types::OwnedValue};
use futures::stream::{FuturesUnordered, StreamExt};
use itertools::Itertools;

use crate::{
    client::{client_by_server_id, client_by_server_name},
    index::{
        ranged::{client::cursor::ClientCursor, lsm::btree::Ordering},
        EntryKey, IndexerClients, SCHEMA_SCAN_PATT_SIZE,
    },
    ram::cell::{OwnedCell, ReadError},
};

const SCAN_BUFFER_SIZE: u16 = 64;

pub struct IndexedDataClient {
    conshash: Arc<ConsistentHashing>,
    index_clients: Arc<IndexerClients>,
}

pub struct DataCursor<'a> {
    index_cursor: Option<ClientCursor>,
    buffer: Vec<OwnedCell>,
    projection: Vec<u64>,
    selection: Expr,
    proc: Expr,
    client: &'a IndexedDataClient,
    pos: usize,
}

impl IndexedDataClient {
    pub fn new(conshash: &Arc<ConsistentHashing>, raft_client: &Arc<RaftClient>) -> Self {
        Self {
            conshash: conshash.clone(),
            index_clients: Arc::new(IndexerClients::new(conshash, raft_client)),
        }
    }
    pub async fn range_index_scan<'a>(
        &self,
        schema: u32,
        field: u64,
        key: u64,
        selection: OwnedValue,
        projection: OwnedValue,
    ) -> DataCursor<'a> {
        unimplemented!()
    }
    pub async fn scan_all<'a>(
        &'a self,
        schema: u32,
        projection: Vec<u64>, // Column array
        selection: Expr,      // Checker expression
        proc: Expr,
        ordering: Ordering,
    ) -> Result<DataCursor<'a>, RPCError> {
        let key = EntryKey::for_schema(schema);
        let index_cursor = self
            .index_clients
            .range_seek(
                &key,
                ordering,
                SCAN_BUFFER_SIZE,
                Some(SCHEMA_SCAN_PATT_SIZE),
            )
            .await?;
        let mut cursor = DataCursor {
            index_cursor,
            projection,
            selection,
            proc,
            client: self,
            buffer: vec![],
            pos: 0,
        };
        cursor.refresh_batch().await;
        Ok(cursor)
    }
}

impl<'a> DataCursor<'a> {
    pub async fn next(&mut self) -> Result<Option<OwnedCell>, RPCError> {
        if self.buffer.len() <= self.pos {
            if self.next_block().await? {
                if !self.refresh_batch().await {
                    return Ok(None);
                }
            } else {
                return Ok(None);
            }
        }
        let cell = mem::take(&mut self.buffer[self.pos]);
        self.pos += 1;
        return Ok(Some(cell));
    }

    pub async fn next_block(&mut self) -> Result<bool, RPCError> {
        if let Some(cursor) = &mut self.index_cursor {
            if cursor.next_block().await? {
                return Ok(true);
            }
        }
        // If cannot get next block, set the index cursor to none
        // We are done with this cursor
        self.index_cursor = None;
        self.buffer = vec![];
        self.pos = 0;
        return Ok(false);
    }

    pub async fn refresh_batch(&mut self) -> bool {
        if let Some(cursor) = &self.index_cursor {
            let all_ids = cursor.current_block();
            let mut tasks = all_ids
                .iter()
                .enumerate()
                .filter_map(|(i, id)| {
                    self.client
                        .conshash
                        .get_server_id_by(id)
                        .map(|sid| (i, sid, id))
                })
                .group_by(|(_i, sid, _id)| *sid)
                .into_iter()
                .map(|(sid, pairs)| {
                    let mut ids = vec![];
                    let mut idx = vec![];
                    for (i, _, id) in pairs {
                        idx.push(i);
                        ids.push(*id);
                    }
                    let projection = self.projection.clone();
                    let selection = self.selection.clone();
                    let proc = self.proc.clone();
                    let server_name = self.client.conshash.to_server_name(sid);
                    async move {
                        match client_by_server_name(sid, server_name).await {
                            Ok(client) => {
                                let read_res = client
                                    .read_all_cells_proced(ids, projection, selection, proc)
                                    .await
                                    .map(|v| v.into_iter().zip(idx).collect_vec());
                                match read_res {
                                    Ok(cells) => Ok(cells
                                        .into_iter()
                                        .filter_map(|(c, i)| c.ok().map(|c| (c, i)))
                                        .collect_vec()),
                                    Err(e) => return Err(e),
                                }
                            }
                            Err(e) => return Err(e),
                        }
                    }
                })
                .collect::<FuturesUnordered<_>>();
            let mut all_cells = vec![];
            while let Some(task_res) = tasks.next().await {
                if let Ok(mut cells) = task_res {
                    all_cells.append(&mut cells);
                }
            }
            all_cells.sort_by(|(_, i1), (_, i2)| i1.cmp(i2));
            self.buffer = all_cells.into_iter().map(|(c, _)| c).collect_vec();
            self.pos = 0;
            true
        } else {
            self.buffer = vec![];
            self.pos = 0;
            false
        }
    }
}

#[cfg(test)]
mod test {
    use crate::{
        client,
        index::ranged::lsm::btree::Ordering,
        query::data_client::IndexedDataClient,
        ram::{
            cell::OwnedCell,
            schema::{Field, Schema},
        },
        server::*,
    };
    use dovahkiin::{expr::serde::Expr, types::*};
    use std::sync::Arc;

    #[tokio::test(flavor = "multi_thread")]
    async fn scan_all() {
        const DATA: &'static str = "DATA";
        let _ = env_logger::try_init();
        let server_addr = String::from("127.0.0.1:6701");
        let server_group = String::from("smoke_test");
        let server = NebServer::new_from_opts(
            &ServerOptions {
                chunk_count: 1,
                memory_size: 512 * 1024 * 1024,
                backup_storage: None,
                wal_storage: None,
                index_enabled: false,
                services: vec![Service::Cell, Service::Query],
            },
            &server_addr,
            &server_group,
        )
        .await;
        // Require schema to be scannable to insert special scan key to the range indexer
        let schema_id = 123;
        let schema = Schema::new_with_id(
            schema_id,
            &String::from("schema"),
            None,
            Field::new(
                "*",
                Type::Map,
                false,
                false,
                Some(vec![Field::new(
                    DATA,
                    Type::U64,
                    false,
                    false,
                    None,
                    vec![],
                )]),
                vec![],
            ),
            false,
            true, // Scannable
        );
        let client = server.data_client(&vec![server_addr]).await.unwrap();
        client.new_schema_with_id(schema).await.unwrap().unwrap();
        let num = 10240;
        for i in 0..num {
            let id = Id::new(1, i);
            let mut value = OwnedValue::Map(OwnedMap::new());
            value[DATA] = OwnedValue::U64(i);
            let cell = OwnedCell::new_with_id(schema_id, &id, value);
            client.write_cell(cell).await.unwrap().unwrap();
        }
        let idx_data_client = server.indexed_data_client();
        let mut cursor = idx_data_client
            .scan_all(
                schema_id,
                vec![],
                Expr::nothing(),
                Expr::nothing(),
                Ordering::Forward,
            )
            .await
            .unwrap();
        for i in 0..num {
            let id = Id::new(1, i);
            let cell_res = cursor.next().await.unwrap();
            let cell = cell_res.unwrap();
            assert_eq!(id, cell.id());
        }
    }
}
<commit_msg>logging test case id<commit_after>use std::{mem, sync::Arc};

use bifrost::{conshash::ConsistentHashing, raft::client::RaftClient, rpc::RPCError};
use dovahkiin::{expr::serde::Expr, types::OwnedValue};
use futures::stream::{FuturesUnordered, StreamExt};
use itertools::Itertools;

use crate::{
    client::{client_by_server_id, client_by_server_name},
    index::{
        ranged::{client::cursor::ClientCursor, lsm::btree::Ordering},
        EntryKey, IndexerClients, SCHEMA_SCAN_PATT_SIZE,
    },
    ram::cell::{OwnedCell, ReadError},
};

const SCAN_BUFFER_SIZE: u16 = 64;

pub struct IndexedDataClient {
    conshash: Arc<ConsistentHashing>,
    index_clients: Arc<IndexerClients>,
}

pub struct DataCursor<'a> {
    index_cursor: Option<ClientCursor>,
    buffer: Vec<OwnedCell>,
    projection: Vec<u64>,
    selection: Expr,
    proc: Expr,
    client: &'a IndexedDataClient,
    pos: usize,
}

impl IndexedDataClient {
    pub fn new(conshash: &Arc<ConsistentHashing>, raft_client: &Arc<RaftClient>) -> Self {
        Self {
            conshash: conshash.clone(),
            index_clients: Arc::new(IndexerClients::new(conshash, raft_client)),
        }
    }
    pub async fn range_index_scan<'a>(
        &self,
        schema: u32,
        field: u64,
        key: u64,
        selection: OwnedValue,
        projection: OwnedValue,
    ) -> DataCursor<'a> {
        unimplemented!()
    }
    pub async fn scan_all<'a>(
        &'a self,
        schema: u32,
        projection: Vec<u64>, // Column array
        selection: Expr,      // Checker expression
        proc: Expr,
        ordering: Ordering,
    ) -> Result<DataCursor<'a>, RPCError> {
        let key = EntryKey::for_schema(schema);
        let index_cursor = self
            .index_clients
            .range_seek(
                &key,
                ordering,
                SCAN_BUFFER_SIZE,
                Some(SCHEMA_SCAN_PATT_SIZE),
            )
            .await?;
        let mut cursor = DataCursor {
            index_cursor,
            projection,
            selection,
            proc,
            client: self,
            buffer: vec![],
            pos: 0,
        };
        cursor.refresh_batch().await;
        Ok(cursor)
    }
}

impl<'a> DataCursor<'a> {
    pub async fn next(&mut self) -> Result<Option<OwnedCell>, RPCError> {
        if self.buffer.len() <= self.pos {
            if self.next_block().await? {
                if !self.refresh_batch().await {
                    return Ok(None);
                }
            } else {
                return Ok(None);
            }
        }
        let cell = mem::take(&mut self.buffer[self.pos]);
        self.pos += 1;
        return Ok(Some(cell));
    }

    pub async fn next_block(&mut self) -> Result<bool, RPCError> {
        if let Some(cursor) = &mut self.index_cursor {
            if cursor.next_block().await? {
                return Ok(true);
            }
        }
        // If cannot get next block, set the index cursor to none
        // We are done with this cursor
        self.index_cursor = None;
        self.buffer = vec![];
        self.pos = 0;
        return Ok(false);
    }

    pub async fn refresh_batch(&mut self) -> bool {
        if let Some(cursor) = &self.index_cursor {
            let all_ids = cursor.current_block();
            let mut tasks = all_ids
                .iter()
                .enumerate()
                .filter_map(|(i, id)| {
                    self.client
                        .conshash
                        .get_server_id_by(id)
                        .map(|sid| (i, sid, id))
                })
                .group_by(|(_i, sid, _id)| *sid)
                .into_iter()
                .map(|(sid, pairs)| {
                    let mut ids = vec![];
                    let mut idx = vec![];
                    for (i, _, id) in pairs {
                        idx.push(i);
                        ids.push(*id);
                    }
                    let projection = self.projection.clone();
                    let selection = self.selection.clone();
                    let proc = self.proc.clone();
                    let server_name = self.client.conshash.to_server_name(sid);
                    async move {
                        match client_by_server_name(sid, server_name).await {
                            Ok(client) => {
                                let read_res = client
                                    .read_all_cells_proced(ids, projection, selection, proc)
                                    .await
                                    .map(|v| v.into_iter().zip(idx).collect_vec());
                                match read_res {
                                    Ok(cells) => Ok(cells
                                        .into_iter()
                                        .filter_map(|(c, i)| c.ok().map(|c| (c, i)))
                                        .collect_vec()),
                                    Err(e) => return Err(e),
                                }
                            }
                            Err(e) => return Err(e),
                        }
                    }
                })
                .collect::<FuturesUnordered<_>>();
            let mut all_cells = vec![];
            while let Some(task_res) = tasks.next().await {
                if let Ok(mut cells) = task_res {
                    all_cells.append(&mut cells);
                }
            }
            all_cells.sort_by(|(_, i1), (_, i2)| i1.cmp(i2));
            self.buffer = all_cells.into_iter().map(|(c, _)| c).collect_vec();
            self.pos = 0;
            true
        } else {
            self.buffer = vec![];
            self.pos = 0;
            false
        }
    }
}

#[cfg(test)]
mod test {
    use crate::{
        index::ranged::lsm::btree::Ordering,
        ram::{
            cell::OwnedCell,
            schema::{Field, Schema},
        },
        server::*,
    };
    use dovahkiin::{expr::serde::Expr, types::*};

    #[tokio::test(flavor = "multi_thread")]
    async fn scan_all() {
        const DATA: &'static str = "DATA";
        let _ = env_logger::try_init();
        let server_addr = String::from("127.0.0.1:6701");
        let server_group = String::from("smoke_test");
        let server = NebServer::new_from_opts(
            &ServerOptions {
                chunk_count: 1,
                memory_size: 512 * 1024 * 1024,
                backup_storage: None,
                wal_storage: None,
                index_enabled: false,
                services: vec![Service::Cell, Service::Query],
            },
            &server_addr,
            &server_group,
        )
        .await;
        // Require schema to be scannable to insert special scan key to the range indexer
        let schema_id = 123;
        let schema = Schema::new_with_id(
            schema_id,
            &String::from("schema"),
            None,
            Field::new(
                "*",
                Type::Map,
                false,
                false,
                Some(vec![Field::new(
                    DATA,
                    Type::U64,
                    false,
                    false,
                    None,
                    vec![],
                )]),
                vec![],
            ),
            false,
            true, // Scannable
        );
        let client = server.data_client(&vec![server_addr]).await.unwrap();
        client.new_schema_with_id(schema).await.unwrap().unwrap();
        let num = 10240;
        for i in 0..num {
            let id = Id::new(1, i);
            let mut value = OwnedValue::Map(OwnedMap::new());
            value[DATA] = OwnedValue::U64(i);
            let cell = OwnedCell::new_with_id(schema_id, &id, value);
            client.write_cell(cell).await.unwrap().unwrap();
        }
        let idx_data_client = server.indexed_data_client();
        let mut cursor = idx_data_client
            .scan_all(
                schema_id,
                vec![],
                Expr::nothing(),
                Expr::nothing(),
                Ordering::Forward,
            )
            .await
            .unwrap();
        for i in 0..num {
            let id = Id::new(1, i);
            let cell_res = match cursor.next().await {
                Ok(r) => r,
                Err(e) => {
                    panic!("Error next for {}, {:?}", i, e);
                }
            };
            let cell = match cell_res {
                Some(c) => c,
                None => {
                    panic!("Have none for {}", i);
                }
            };
            assert_eq!(id, cell.id());
        }
    }
}
<|endoftext|>