<commit_before>use std::iter::FromIterator;
use std::slice;
use std::vec;

#[cfg_attr(feature = "extra-traits", derive(Eq, PartialEq, Hash, Debug))]
#[cfg_attr(feature = "clone-impls", derive(Clone))]
pub struct Delimited<T, D> {
    inner: Vec<(T, Option<D>)>
}

impl<T, D> Delimited<T, D> {
    pub fn new() -> Delimited<T, D> {
        Delimited {
            inner: Vec::new(),
        }
    }

    pub fn is_empty(&self) -> bool {
        self.inner.len() == 0
    }

    pub fn len(&self) -> usize {
        self.inner.len()
    }

    pub fn get(&self, idx: usize) -> Element<&T, &D> {
        let (ref t, ref d) = self.inner[idx];
        match *d {
            Some(ref d) => Element::Delimited(t, d),
            None => Element::End(t),
        }
    }

    pub fn get_mut(&mut self, idx: usize) -> Element<&mut T, &mut D> {
        let (ref mut t, ref mut d) = self.inner[idx];
        match *d {
            Some(ref mut d) => Element::Delimited(t, d),
            None => Element::End(t),
        }
    }

    pub fn iter(&self) -> Iter<T, D> {
        Iter { inner: self.inner.iter() }
    }

    pub fn iter_mut(&mut self) -> IterMut<T, D> {
        IterMut { inner: self.inner.iter_mut() }
    }

    pub fn items(&self) -> Items<T, D> {
        Items { inner: self.inner.iter() }
    }

    pub fn push(&mut self, token: Element<T, D>) {
        assert!(self.is_empty() || self.trailing_delim());
        match token {
            Element::Delimited(t, d) => self.inner.push((t, Some(d))),
            Element::End(t) => self.inner.push((t, None)),
        }
    }

    pub fn push_first(&mut self, token: T) {
        assert!(self.is_empty());
        self.inner.push((token, None));
    }

    pub fn push_next(&mut self, token: T, delimiter: D) {
        self.push_trailing(delimiter);
        self.inner.push((token, None));
    }

    pub fn push_trailing(&mut self, delimiter: D) {
        let len = self.len();
        assert!(self.inner[len - 1].1.is_none());
        self.inner[len - 1].1 = Some(delimiter);
    }

    pub fn push_default(&mut self, token: T) where D: Default {
        if self.is_empty() {
            self.inner.push((token, None));
        } else {
            self.push_next(token, D::default());
        }
    }

    pub fn pop(&mut self) -> Option<Element<T, D>> {
        self.inner.pop().map(|e| {
            match e {
                (t, Some(d)) => Element::Delimited(t, d),
                (t, None) => Element::End(t),
            }
        })
    }

    pub fn into_vec(self) -> Vec<T> {
        self.inner.into_iter().map(|t| t.0).collect()
    }

    pub fn trailing_delim(&self) -> bool {
        self.inner[self.inner.len() - 1].1.is_some()
    }
}

impl<T, D> From<Vec<(T, Option<D>)>> for Delimited<T, D> {
    fn from(v: Vec<(T, Option<D>)>) -> Self {
        Delimited {
            inner: v,
        }
    }
}

impl<T, D> From<Vec<T>> for Delimited<T, D>
    where D: Default,
{
    fn from(v: Vec<T>) -> Self {
        let last = v.len() - 1;
        Delimited {
            inner: v.into_iter().enumerate().map(|(i, item)| {
                (item, if i == last {None} else {Some(D::default())})
            }).collect(),
        }
    }
}

impl<T, D> FromIterator<Element<T, D>> for Delimited<T, D> {
    fn from_iter<I: IntoIterator<Item = Element<T, D>>>(i: I) -> Self {
        let mut ret = Delimited::new();
        for element in i {
            match element {
                Element::Delimited(a, b) => ret.inner.push((a, Some(b))),
                Element::End(a) => ret.inner.push((a, None)),
            }
        }
        ret
    }
}

impl<'a, T, D> IntoIterator for &'a Delimited<T, D> {
    type Item = Element<&'a T, &'a D>;
    type IntoIter = Iter<'a, T, D>;

    fn into_iter(self) -> Iter<'a, T, D> {
        <Delimited<T, D>>::iter(self)
    }
}

impl<T, D> IntoIterator for Delimited<T, D> {
    type Item = Element<T, D>;
    type IntoIter = IntoIter<T, D>;

    fn into_iter(self) -> IntoIter<T, D> {
        IntoIter { inner: self.inner.into_iter() }
    }
}

impl<T, D> Default for Delimited<T, D> {
    fn default() -> Self {
        Delimited::new()
    }
}

pub struct Iter<'a, T: 'a, D: 'a> {
    inner: slice::Iter<'a, (T, Option<D>)>,
}

impl<'a, T, D> Iterator for Iter<'a, T, D> {
    type Item = Element<&'a T, &'a D>;

    fn next(&mut self) -> Option<Element<&'a T, &'a D>> {
        self.inner.next().map(|pair| {
            match pair.1 {
                Some(ref delimited) => Element::Delimited(&pair.0, delimited),
                None => Element::End(&pair.0),
            }
        })
    }
}

pub struct IterMut<'a, T: 'a, D: 'a> {
    inner: slice::IterMut<'a, (T, Option<D>)>,
}

impl<'a, T, D> Iterator for IterMut<'a, T, D> {
    type Item = Element<&'a mut T, &'a mut D>;

    fn next(&mut self) -> Option<Element<&'a mut T, &'a mut D>> {
        self.inner.next().map(|pair| {
            match pair.1 {
                Some(ref mut delimited) => Element::Delimited(&mut pair.0, delimited),
                None => Element::End(&mut pair.0),
            }
        })
    }
}

pub struct Items<'a, T: 'a, D: 'a> {
    inner: slice::Iter<'a, (T, Option<D>)>,
}

impl<'a, T, D> Iterator for Items<'a, T, D> {
    type Item = &'a T;

    fn next(&mut self) -> Option<&'a T> {
        self.inner.next().map(|pair| &pair.0)
    }
}

pub struct IntoIter<T, D> {
    inner: vec::IntoIter<(T, Option<D>)>,
}

impl<T, D> Iterator for IntoIter<T, D> {
    type Item = Element<T, D>;

    fn next(&mut self) -> Option<Element<T, D>> {
        self.inner.next().map(|pair| {
            match pair.1 {
                Some(v) => Element::Delimited(pair.0, v),
                None => Element::End(pair.0)
            }
        })
    }
}

pub enum Element<T, D> {
    Delimited(T, D),
    End(T),
}

impl<T, D> Element<T, D> {
    pub fn into_item(self) -> T {
        match self {
            Element::Delimited(t, _) |
            Element::End(t) => t,
        }
    }

    pub fn item(&self) -> &T {
        match *self {
            Element::Delimited(ref t, _) |
            Element::End(ref t) => t,
        }
    }

    pub fn item_mut(&mut self) -> &mut T {
        match *self {
            Element::Delimited(ref mut t, _) |
            Element::End(ref mut t) => t,
        }
    }

    pub fn delimiter(&self) -> Option<&D> {
        match *self {
            Element::Delimited(_, ref d) => Some(d),
            Element::End(_) => None,
        }
    }
}

#[cfg(feature = "parsing")]
mod parsing {
    use super::Delimited;
    use {PResult, Cursor, Synom, parse_error};

    impl<T, D> Delimited<T, D>
        where T: Synom,
              D: Synom,
    {
        pub fn parse_separated(input: Cursor) -> PResult<Self>
        {
            Self::parse(input, T::parse, false)
        }

        pub fn parse_separated_nonempty(input: Cursor) -> PResult<Self>
        {
            Self::parse_separated_nonempty_with(input, T::parse)
        }

        pub fn parse_terminated(input: Cursor) -> PResult<Self>
        {
            Self::parse_terminated_with(input, T::parse)
        }
    }

    impl<T, D> Delimited<T, D>
        where D: Synom,
    {
        pub fn parse_separated_nonempty_with(
                input: Cursor,
                parse: fn(Cursor) -> PResult<T>)
            -> PResult<Self>
        {
            match Self::parse(input, parse, false) {
                Ok((_, ref b)) if b.is_empty() => parse_error(),
                other => other,
            }
        }

        pub fn parse_terminated_with(
                input: Cursor,
                parse: fn(Cursor) -> PResult<T>)
            -> PResult<Self>
        {
            Self::parse(input, parse, true)
        }

        fn parse(mut input: Cursor,
                 parse: fn(Cursor) -> PResult<T>,
                 terminated: bool)
            -> PResult<Self>
        {
            let mut res = Delimited::new();

            // get the first element
            match parse(input) {
                Err(_) => Ok((input, res)),
                Ok((i, o)) => {
                    if i == input {
                        return parse_error();
                    }
                    input = i;
                    res.push_first(o);

                    // get the separator first
                    while let Ok((i2, s)) = D::parse(input) {
                        if i2 == input {
                            break;
                        }

                        // get the element next
                        if let Ok((i3, o3)) = parse(i2) {
                            if i3 == i2 {
                                break;
                            }
                            res.push_next(o3, s);
                            input = i3;
                        } else {
                            break;
                        }
                    }
                    if terminated {
                        if let Ok((after, sep)) = D::parse(input) {
                            res.push_trailing(sep);
                            input = after;
                        }
                    }
                    Ok((input, res))
                }
            }
        }
    }
}

#[cfg(feature = "printing")]
mod printing {
    use super::*;
    use quote::{Tokens, ToTokens};

    impl<T, D> ToTokens for Delimited<T, D>
        where T: ToTokens,
              D: ToTokens,
    {
        fn to_tokens(&self, tokens: &mut Tokens) {
            tokens.append_all(self.iter())
        }
    }

    impl<T, D> ToTokens for Element<T, D>
        where T: ToTokens,
              D: ToTokens,
    {
        fn to_tokens(&self, tokens: &mut Tokens) {
            match *self {
                Element::Delimited(ref a, ref b) => {
                    a.to_tokens(tokens);
                    b.to_tokens(tokens);
                }
                Element::End(ref a) => a.to_tokens(tokens),
            }
        }
    }
}
<commit_msg>Fix implementation of Delimited::push_default<commit_after>use std::iter::FromIterator;
use std::slice;
use std::vec;

#[cfg_attr(feature = "extra-traits", derive(Eq, PartialEq, Hash, Debug))]
#[cfg_attr(feature = "clone-impls", derive(Clone))]
pub struct Delimited<T, D> {
    inner: Vec<(T, Option<D>)>
}

impl<T, D> Delimited<T, D> {
    pub fn new() -> Delimited<T, D> {
        Delimited {
            inner: Vec::new(),
        }
    }

    pub fn is_empty(&self) -> bool {
        self.inner.len() == 0
    }

    pub fn len(&self) -> usize {
        self.inner.len()
    }

    pub fn get(&self, idx: usize) -> Element<&T, &D> {
        let (ref t, ref d) = self.inner[idx];
        match *d {
            Some(ref d) => Element::Delimited(t, d),
            None => Element::End(t),
        }
    }

    pub fn get_mut(&mut self, idx: usize) -> Element<&mut T, &mut D> {
        let (ref mut t, ref mut d) = self.inner[idx];
        match *d {
            Some(ref mut d) => Element::Delimited(t, d),
            None => Element::End(t),
        }
    }

    pub fn iter(&self) -> Iter<T, D> {
        Iter { inner: self.inner.iter() }
    }

    pub fn iter_mut(&mut self) -> IterMut<T, D> {
        IterMut { inner: self.inner.iter_mut() }
    }

    pub fn items(&self) -> Items<T, D> {
        Items { inner: self.inner.iter() }
    }

    pub fn push(&mut self, token: Element<T, D>) {
        assert!(self.is_empty() || self.trailing_delim());
        match token {
            Element::Delimited(t, d) => self.inner.push((t, Some(d))),
            Element::End(t) => self.inner.push((t, None)),
        }
    }

    pub fn push_first(&mut self, token: T) {
        assert!(self.is_empty());
        self.inner.push((token, None));
    }

    pub fn push_next(&mut self, token: T, delimiter: D) {
        self.push_trailing(delimiter);
        self.inner.push((token, None));
    }

    pub fn push_trailing(&mut self, delimiter: D) {
        let len = self.len();
        assert!(self.inner[len - 1].1.is_none());
        self.inner[len - 1].1 = Some(delimiter);
    }

    pub fn push_default(&mut self, token: T) where D: Default {
        if self.is_empty() || self.trailing_delim() {
            self.inner.push((token, None));
        } else {
            self.push_next(token, D::default());
        }
    }

    pub fn pop(&mut self) -> Option<Element<T, D>> {
        self.inner.pop().map(|e| {
            match e {
                (t, Some(d)) => Element::Delimited(t, d),
                (t, None) => Element::End(t),
            }
        })
    }

    pub fn into_vec(self) -> Vec<T> {
        self.inner.into_iter().map(|t| t.0).collect()
    }

    pub fn trailing_delim(&self) -> bool {
        self.inner[self.inner.len() - 1].1.is_some()
    }
}

impl<T, D> From<Vec<(T, Option<D>)>> for Delimited<T, D> {
    fn from(v: Vec<(T, Option<D>)>) -> Self {
        Delimited {
            inner: v,
        }
    }
}

impl<T, D> From<Vec<T>> for Delimited<T, D>
    where D: Default,
{
    fn from(v: Vec<T>) -> Self {
        let last = v.len() - 1;
        Delimited {
            inner: v.into_iter().enumerate().map(|(i, item)| {
                (item, if i == last {None} else {Some(D::default())})
            }).collect(),
        }
    }
}

impl<T, D> FromIterator<Element<T, D>> for Delimited<T, D> {
    fn from_iter<I: IntoIterator<Item = Element<T, D>>>(i: I) -> Self {
        let mut ret = Delimited::new();
        for element in i {
            match element {
                Element::Delimited(a, b) => ret.inner.push((a, Some(b))),
                Element::End(a) => ret.inner.push((a, None)),
            }
        }
        ret
    }
}

impl<'a, T, D> IntoIterator for &'a Delimited<T, D> {
    type Item = Element<&'a T, &'a D>;
    type IntoIter = Iter<'a, T, D>;

    fn into_iter(self) -> Iter<'a, T, D> {
        <Delimited<T, D>>::iter(self)
    }
}

impl<T, D> IntoIterator for Delimited<T, D> {
    type Item = Element<T, D>;
    type IntoIter = IntoIter<T, D>;

    fn into_iter(self) -> IntoIter<T, D> {
        IntoIter { inner: self.inner.into_iter() }
    }
}

impl<T, D> Default for Delimited<T, D> {
    fn default() -> Self {
        Delimited::new()
    }
}

pub struct Iter<'a, T: 'a, D: 'a> {
    inner: slice::Iter<'a, (T, Option<D>)>,
}

impl<'a, T, D> Iterator for Iter<'a, T, D> {
    type Item = Element<&'a T, &'a D>;

    fn next(&mut self) -> Option<Element<&'a T, &'a D>> {
        self.inner.next().map(|pair| {
            match pair.1 {
                Some(ref delimited) => Element::Delimited(&pair.0, delimited),
                None => Element::End(&pair.0),
            }
        })
    }
}

pub struct IterMut<'a, T: 'a, D: 'a> {
    inner: slice::IterMut<'a, (T, Option<D>)>,
}

impl<'a, T, D> Iterator for IterMut<'a, T, D> {
    type Item = Element<&'a mut T, &'a mut D>;

    fn next(&mut self) -> Option<Element<&'a mut T, &'a mut D>> {
        self.inner.next().map(|pair| {
            match pair.1 {
                Some(ref mut delimited) => Element::Delimited(&mut pair.0, delimited),
                None => Element::End(&mut pair.0),
            }
        })
    }
}

pub struct Items<'a, T: 'a, D: 'a> {
    inner: slice::Iter<'a, (T, Option<D>)>,
}

impl<'a, T, D> Iterator for Items<'a, T, D> {
    type Item = &'a T;

    fn next(&mut self) -> Option<&'a T> {
        self.inner.next().map(|pair| &pair.0)
    }
}

pub struct IntoIter<T, D> {
    inner: vec::IntoIter<(T, Option<D>)>,
}

impl<T, D> Iterator for IntoIter<T, D> {
    type Item = Element<T, D>;

    fn next(&mut self) -> Option<Element<T, D>> {
        self.inner.next().map(|pair| {
            match pair.1 {
                Some(v) => Element::Delimited(pair.0, v),
                None => Element::End(pair.0)
            }
        })
    }
}

pub enum Element<T, D> {
    Delimited(T, D),
    End(T),
}

impl<T, D> Element<T, D> {
    pub fn into_item(self) -> T {
        match self {
            Element::Delimited(t, _) |
            Element::End(t) => t,
        }
    }

    pub fn item(&self) -> &T {
        match *self {
            Element::Delimited(ref t, _) |
            Element::End(ref t) => t,
        }
    }

    pub fn item_mut(&mut self) -> &mut T {
        match *self {
            Element::Delimited(ref mut t, _) |
            Element::End(ref mut t) => t,
        }
    }

    pub fn delimiter(&self) -> Option<&D> {
        match *self {
            Element::Delimited(_, ref d) => Some(d),
            Element::End(_) => None,
        }
    }
}

#[cfg(feature = "parsing")]
mod parsing {
    use super::Delimited;
    use {PResult, Cursor, Synom, parse_error};

    impl<T, D> Delimited<T, D>
        where T: Synom,
              D: Synom,
    {
        pub fn parse_separated(input: Cursor) -> PResult<Self>
        {
            Self::parse(input, T::parse, false)
        }

        pub fn parse_separated_nonempty(input: Cursor) -> PResult<Self>
        {
            Self::parse_separated_nonempty_with(input, T::parse)
        }

        pub fn parse_terminated(input: Cursor) -> PResult<Self>
        {
            Self::parse_terminated_with(input, T::parse)
        }
    }

    impl<T, D> Delimited<T, D>
        where D: Synom,
    {
        pub fn parse_separated_nonempty_with(
                input: Cursor,
                parse: fn(Cursor) -> PResult<T>)
            -> PResult<Self>
        {
            match Self::parse(input, parse, false) {
                Ok((_, ref b)) if b.is_empty() => parse_error(),
                other => other,
            }
        }

        pub fn parse_terminated_with(
                input: Cursor,
                parse: fn(Cursor) -> PResult<T>)
            -> PResult<Self>
        {
            Self::parse(input, parse, true)
        }

        fn parse(mut input: Cursor,
                 parse: fn(Cursor) -> PResult<T>,
                 terminated: bool)
            -> PResult<Self>
        {
            let mut res = Delimited::new();

            // get the first element
            match parse(input) {
                Err(_) => Ok((input, res)),
                Ok((i, o)) => {
                    if i == input {
                        return parse_error();
                    }
                    input = i;
                    res.push_first(o);

                    // get the separator first
                    while let Ok((i2, s)) = D::parse(input) {
                        if i2 == input {
                            break;
                        }

                        // get the element next
                        if let Ok((i3, o3)) = parse(i2) {
                            if i3 == i2 {
                                break;
                            }
                            res.push_next(o3, s);
                            input = i3;
                        } else {
                            break;
                        }
                    }
                    if terminated {
                        if let Ok((after, sep)) = D::parse(input) {
                            res.push_trailing(sep);
                            input = after;
                        }
                    }
                    Ok((input, res))
                }
            }
        }
    }
}

#[cfg(feature = "printing")]
mod printing {
    use super::*;
    use quote::{Tokens, ToTokens};

    impl<T, D> ToTokens for Delimited<T, D>
        where T: ToTokens,
              D: ToTokens,
    {
        fn to_tokens(&self, tokens: &mut Tokens) {
            tokens.append_all(self.iter())
        }
    }

    impl<T, D> ToTokens for Element<T, D>
        where T: ToTokens,
              D: ToTokens,
    {
        fn to_tokens(&self, tokens: &mut Tokens) {
            match *self {
                Element::Delimited(ref a, ref b) => {
                    a.to_tokens(tokens);
                    b.to_tokens(tokens);
                }
                Element::End(ref a) => a.to_tokens(tokens),
            }
        }
    }
}
<|endoftext|>


<commit_before>pub fn sort(word: &'static str) -> String {
    let mut chars: Vec<char> = word.chars().collect();
    chars.sort();
    return chars.into_iter().collect();
}

fn main() {
    let mystr1: &'static str = "This is a readonly string";

    for c in mystr1.chars().rev() {
        print!("{}", c);
    }

    println!("");

    let mut mystr2 = String::new();
    for c in mystr1.chars() {
        mystr2.push(c);
    }

    println!("{}", mystr2);

    mystr2 = "Hello World".to_string();

    println!("{}", mystr2);

    let num: u32 = 12;

    mystr2 = num.to_string();

    println!("{}", mystr2);

    let str = sort("abzerfdsgyiof");
    print!("{}", str);
}<commit_msg>added extract num example<commit_after>pub fn sort(word: &'static str) -> String {
    let mut chars: Vec<char> = word.chars().collect();
    chars.sort();
    return chars.into_iter().collect();
}

fn extract_numbers(s: &str) -> Vec<String> {
    let mut num = String::new();
    let mut m = vec![];

    for c in s.chars() {
        if c.is_numeric() {
            num.push(c);
        }
        else {
            if !num.is_empty() {
                m.push(num.clone());
                num.clear();
            }
        }
    }

    if !num.is_empty() {
        m.push(num);
    }

    return m;
}

fn main() {
    let mystr1: &'static str = "This is a readonly string";

    for c in mystr1.chars().rev() {
        print!("{}", c);
    }

    println!("");

    let mut mystr2 = String::new();
    for c in mystr1.chars() {
        mystr2.push(c);
    }

    println!("{}", mystr2);

    mystr2 = "Hello World".to_string();

    println!("{}", mystr2);

    let num: u32 = 12;

    mystr2 = num.to_string();

    println!("{}", mystr2);

    let str = sort("abzerfdsgyiof");
    print!("{}", str);

    let mystr3 = "x12y7".to_string();
    let m: Vec<String> = extract_numbers(&mystr3); // -> ( "12", "7" )

    for x in m.iter() {
        println!("{}", x);
    }
}<|endoftext|>


<commit_before><commit_msg>Remove useless code<commit_after><|endoftext|>


<commit_before>use lib::ParseFrom;
use std::collections::HashSet;

#[derive(PartialEq, Eq, Hash, Debug, Clone)]
pub enum Item {
    Potato,
    Berry,
    TreeSap,
}

impl ParseFrom<i32> for Item {
    fn parse (i: i32) -> Result<Self, String> {
        match i {
            0 => Ok(Item::Potato),
            1 => Ok(Item::Berry),
            2 => Ok(Item::TreeSap),
            _ => Err(format!("Item.parse<i32> failure: unrecognized Item {}", i)),
        }
    }
}

#[derive(Debug,Clone)]
#[allow(non_camel_case_types)]
pub enum Action {
    addItemToInventory(Item),
}

#[derive(Debug, Clone)]
pub struct PlayerState {
    pub inventory: HashSet<Item>,
}

#[derive(Debug, Clone)]
#[allow(dead_code)]
pub enum Player {
    AnonymousPlayer {
        state : PlayerState,
    },
    RegisteredPlayer {
        id    : i32,
        name  : String,
        state : PlayerState,
    },
}

impl Player {
    #[allow(unused_variables)]
    pub fn state (&mut self) -> &mut PlayerState {
        match self {
            &mut Player::AnonymousPlayer { ref mut state } => state,
            &mut Player::RegisteredPlayer { ref mut id, ref mut name, ref mut state } => state,
        }
    }
}

#[allow(non_snake_case)]
pub mod AnonymousPlayer {
    use super::*;
    pub fn new () -> Player {
        let mut new_player_inventory = HashSet::new();
        new_player_inventory.insert(Item::Potato);

        Player::AnonymousPlayer {
            state: PlayerState {
                inventory: new_player_inventory
            }
        }
    }
}

#[allow(non_snake_case,dead_code)]
pub mod RegisteredPlayer {
    use super::*;
    pub fn new (id: i32, name: String) -> Player {
        let mut new_player_inventory = HashSet::new();
        new_player_inventory.insert(Item::Potato);

        Player::RegisteredPlayer {
            id: id,
            name: name,
            state: PlayerState {
                inventory: new_player_inventory
            }
        }
    }
}
<commit_msg>Feature: items are unique<commit_after>use uuid::Uuid;
use lib::ParseFrom;
use std::collections::HashSet;

#[derive(PartialEq, Eq, Hash, Debug, Clone)]
pub enum Item {
    Potato  { id: Uuid },
    Berry   { id: Uuid },
    TreeSap { id: Uuid },
}

impl ParseFrom<i32> for Item {
    fn parse (i: i32) -> Result<Self, String> {
        match i {
            0 => Ok(Potato::new()),
            1 => Ok(Berry::new()),
            2 => Ok(TreeSap::new()),
            _ => Err(format!("Item.parse<i32> failure: unrecognized Item {}", i)),
        }
    }
}

#[allow(non_snake_case)]
mod Potato {
    use super::{Item,Uuid};
    pub fn new () -> Item {
        Item::Potato { id: Uuid::new_v4() }
    }
}

#[allow(non_snake_case)]
mod Berry {
    use super::{Item,Uuid};
    pub fn new () -> Item {
        Item::Berry { id: Uuid::new_v4() }
    }
}

#[allow(non_snake_case)]
mod TreeSap {
    use super::{Item,Uuid};
    pub fn new () -> Item {
        Item::TreeSap { id: Uuid::new_v4() }
    }
}

#[derive(Debug,Clone)]
#[allow(non_camel_case_types)]
pub enum Action {
    addItemToInventory(Item),
}

#[derive(Debug, Clone)]
pub struct PlayerState {
    pub inventory: HashSet<Item>,
}

#[derive(Debug, Clone)]
#[allow(dead_code)]
pub enum Player {
    AnonymousPlayer {
        state : PlayerState,
    },
    RegisteredPlayer {
        id    : i32,
        name  : String,
        state : PlayerState,
    },
}

impl Player {
    #[allow(unused_variables)]
    pub fn state (&mut self) -> &mut PlayerState {
        match self {
            &mut Player::AnonymousPlayer { ref mut state } => state,
            &mut Player::RegisteredPlayer { ref mut id, ref mut name, ref mut state } => state,
        }
    }
}

#[allow(non_snake_case)]
pub mod AnonymousPlayer {
    use super::*;
    pub fn new () -> Player {
        let mut new_player_inventory = HashSet::new();
        new_player_inventory.insert(Potato::new());

        Player::AnonymousPlayer {
            state: PlayerState {
                inventory: new_player_inventory
            }
        }
    }
}

#[allow(non_snake_case,dead_code)]
pub mod RegisteredPlayer {
    use super::*;
    pub fn new (id: i32, name: String) -> Player {
        let mut new_player_inventory = HashSet::new();
        new_player_inventory.insert(Potato::new());

        Player::RegisteredPlayer {
            id: id,
            name: name,
            state: PlayerState {
                inventory: new_player_inventory
            }
        }
    }
}
<|endoftext|>


<commit_before>#![cfg(feature="quickcheck")]
extern crate quickcheck;

extern crate petgraph;

use petgraph::{Graph, Undirected};
use petgraph::algo::{min_spanning_tree, is_cyclic_undirected};

fn prop(g: Graph<(), u32>) -> bool {
    // filter out isolated nodes
    let no_singles = g.filter_map(
        |nx, w| g.neighbors_undirected(nx).next().map(|_| w),
        |_, w| Some(w));
    for i in no_singles.node_indices() {
        assert!(no_singles.neighbors_undirected(i).count() > 0);
    }
    assert_eq!(no_singles.edge_count(), g.edge_count());
    let mst = min_spanning_tree(&no_singles);
    assert!(!is_cyclic_undirected(&mst));
    true
}

fn prop_undir(g: Graph<(), u32, Undirected>) -> bool {
    // filter out isolated nodes
    let no_singles = g.filter_map(
        |nx, w| g.neighbors_undirected(nx).next().map(|_| w),
        |_, w| Some(w));
    for i in no_singles.node_indices() {
        assert!(no_singles.neighbors_undirected(i).count() > 0);
    }
    assert_eq!(no_singles.edge_count(), g.edge_count());
    let mst = min_spanning_tree(&no_singles);
    assert!(!is_cyclic_undirected(&mst));
    true
}

#[test]
fn arbitrary() {
    quickcheck::quickcheck(prop as fn(_) -> bool);
    quickcheck::quickcheck(prop_undir as fn(_) -> bool);
}
<commit_msg>Add quickcheck tests for retain_nodes, retain_edges<commit_after>#![cfg(feature="quickcheck")]
extern crate quickcheck;

extern crate petgraph;

use petgraph::{Graph, Undirected, Directed, EdgeType};
use petgraph::algo::{min_spanning_tree, is_cyclic_undirected, is_isomorphic};

fn prop(g: Graph<(), u32>) -> bool {
    // filter out isolated nodes
    let no_singles = g.filter_map(
        |nx, w| g.neighbors_undirected(nx).next().map(|_| w),
        |_, w| Some(w));
    for i in no_singles.node_indices() {
        assert!(no_singles.neighbors_undirected(i).count() > 0);
    }
    assert_eq!(no_singles.edge_count(), g.edge_count());
    let mst = min_spanning_tree(&no_singles);
    assert!(!is_cyclic_undirected(&mst));
    true
}

fn prop_undir(g: Graph<(), u32, Undirected>) -> bool {
    // filter out isolated nodes
    let no_singles = g.filter_map(
        |nx, w| g.neighbors_undirected(nx).next().map(|_| w),
        |_, w| Some(w));
    for i in no_singles.node_indices() {
        assert!(no_singles.neighbors_undirected(i).count() > 0);
    }
    assert_eq!(no_singles.edge_count(), g.edge_count());
    let mst = min_spanning_tree(&no_singles);
    assert!(!is_cyclic_undirected(&mst));
    true
}

#[test]
fn arbitrary() {
    quickcheck::quickcheck(prop as fn(_) -> bool);
    quickcheck::quickcheck(prop_undir as fn(_) -> bool);
}

#[test]
fn retain_nodes() {
    fn prop<Ty: EdgeType>(mut g: Graph<i32, (), Ty>) -> bool {
        // Remove all negative nodes, these should be randomly spread
        let og = g.clone();
        let nodes = g.node_count();
        let num_negs = g.raw_nodes().iter().filter(|n| n.weight < 0).count();
        let mut removed = 0;
        g.retain_nodes(|g, i| {
            let keep = g[i] >= 0;
            if !keep {
                removed += 1;
            }
            keep
        });
        let num_negs_post = g.raw_nodes().iter().filter(|n| n.weight < 0).count();
        let num_pos_post = g.raw_nodes().iter().filter(|n| n.weight >= 0).count();
        assert_eq!(num_negs_post, 0);
        assert_eq!(removed, num_negs);
        assert_eq!(num_negs + g.node_count(), nodes);
        assert_eq!(num_pos_post, g.node_count());
        if og.edge_count() < 30 {
            // check against filter_map
            let filtered = og.filter_map(|_, w| if *w >= 0 { Some(*w) } else { None },
                                         |_, w| Some(*w));
            assert_eq!(g.node_count(), filtered.node_count());
            assert!(is_isomorphic(&filtered, &g));
        }
        true
    }
    quickcheck::quickcheck(prop as fn(Graph<_, _, Directed>) -> bool);
    quickcheck::quickcheck(prop as fn(Graph<_, _, Undirected>) -> bool);
}

#[test]
fn retain_edges() {
    fn prop<Ty: EdgeType>(mut g: Graph<(), i32, Ty>) -> bool {
        // Remove all negative edges, these should be randomly spread
        let og = g.clone();
        let edges = g.edge_count();
        let num_negs = g.raw_edges().iter().filter(|n| n.weight < 0).count();
        let mut removed = 0;
        g.retain_edges(|g, i| {
            let keep = g[i] >= 0;
            if !keep {
                removed += 1;
            }
            keep
        });
        let num_negs_post = g.raw_edges().iter().filter(|n| n.weight < 0).count();
        let num_pos_post = g.raw_edges().iter().filter(|n| n.weight >= 0).count();
        assert_eq!(num_negs_post, 0);
        assert_eq!(removed, num_negs);
        assert_eq!(num_negs + g.edge_count(), edges);
        assert_eq!(num_pos_post, g.edge_count());
        if og.edge_count() < 30 {
            // check against filter_map
            let filtered = og.filter_map(
                |_, w| Some(*w),
                |_, w| if *w >= 0 { Some(*w) } else { None });
            assert_eq!(g.node_count(), filtered.node_count());
            assert!(is_isomorphic(&filtered, &g));
        }
        true
    }
    quickcheck::quickcheck(prop as fn(Graph<_, _, Directed>) -> bool);
    quickcheck::quickcheck(prop as fn(Graph<_, _, Undirected>) -> bool);
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::{BufRead, BufReader, BufWriter, Seek};
use std::path::Path;
use std::u32;

use crate::codecs::*;

use crate::{ImageOutputFormat, color, error::{UnsupportedError, UnsupportedErrorKind}};
use crate::image;
use crate::dynimage::DynamicImage;
use crate::error::{ImageError, ImageFormatHint, ImageResult};
use crate::image::ImageFormat;
#[allow(unused_imports)]  // When no features are supported
use crate::image::{ImageDecoder, ImageEncoder};

pub(crate) fn open_impl(path: &Path) -> ImageResult<DynamicImage> {
    let fin = match File::open(path) {
        Ok(f) => f,
        Err(err) => return Err(ImageError::IoError(err)),
    };
    let fin = BufReader::new(fin);

    load(fin, ImageFormat::from_path(path)?)
}

/// Create a new image from a Reader.
///
/// Assumes the reader is already buffered. For optimal performance,
/// consider wrapping the reader with a `BufRead::new()`.
///
/// Try [`io::Reader`] for more advanced uses.
///
/// [`io::Reader`]: io/struct.Reader.html
#[allow(unused_variables)]
// r is unused if no features are supported.
pub fn load<R: BufRead + Seek>(r: R, format: ImageFormat) -> ImageResult<DynamicImage> {
    #[allow(unreachable_patterns)]
    // Default is unreachable if all features are supported.
    match format {
        #[cfg(feature = "avif-decoder")]
        image::ImageFormat::Avif => DynamicImage::from_decoder(avif::AvifDecoder::new(r)?),
        #[cfg(feature = "png")]
        image::ImageFormat::Png => DynamicImage::from_decoder(png::PngDecoder::new(r)?),
        #[cfg(feature = "gif")]
        image::ImageFormat::Gif => DynamicImage::from_decoder(gif::GifDecoder::new(r)?),
        #[cfg(feature = "jpeg")]
        image::ImageFormat::Jpeg => DynamicImage::from_decoder(jpeg::JpegDecoder::new(r)?),
        #[cfg(feature = "webp")]
        image::ImageFormat::WebP => DynamicImage::from_decoder(webp::WebPDecoder::new(r)?),
        #[cfg(feature = "tiff")]
        image::ImageFormat::Tiff => DynamicImage::from_decoder(tiff::TiffDecoder::new(r)?),
        #[cfg(feature = "tga")]
        image::ImageFormat::Tga => DynamicImage::from_decoder(tga::TgaDecoder::new(r)?),
        #[cfg(feature = "dds")]
        image::ImageFormat::Dds => DynamicImage::from_decoder(dds::DdsDecoder::new(r)?),
        #[cfg(feature = "bmp")]
        image::ImageFormat::Bmp => DynamicImage::from_decoder(bmp::BmpDecoder::new(r)?),
        #[cfg(feature = "ico")]
        image::ImageFormat::Ico => DynamicImage::from_decoder(ico::IcoDecoder::new(r)?),
        #[cfg(feature = "hdr")]
        image::ImageFormat::Hdr => DynamicImage::from_decoder(hdr::HdrAdapter::new(BufReader::new(r))?),
        #[cfg(feature = "openexr")]
        image::ImageFormat::OpenExr => DynamicImage::from_decoder(openexr::OpenExrDecoder::new(r)?),
        #[cfg(feature = "pnm")]
        image::ImageFormat::Pnm => DynamicImage::from_decoder(pnm::PnmDecoder::new(BufReader::new(r))?),
        #[cfg(feature = "farbfeld")]
        image::ImageFormat::Farbfeld => DynamicImage::from_decoder(farbfeld::FarbfeldDecoder::new(r)?),
        _ => Err(ImageError::Unsupported(ImageFormatHint::Exact(format).into())),
    }
}

pub(crate) fn image_dimensions_impl(path: &Path) -> ImageResult<(u32, u32)> {
    let format = image::ImageFormat::from_path(path)?;

    let fin = File::open(path)?;
    let fin = BufReader::new(fin);

    image_dimensions_with_format_impl(fin, format)
}

#[allow(unused_variables)]
// fin is unused if no features are supported.
pub(crate) fn image_dimensions_with_format_impl<R: BufRead + Seek>(fin: R, format: ImageFormat)
    -> ImageResult<(u32, u32)>
{
    #[allow(unreachable_patterns,unreachable_code)]
    // Default is unreachable if all features are supported.
    // Code after the match is unreachable if none are.
    Ok(match format {
        #[cfg(feature = "avif-decoder")]
        image::ImageFormat::Avif => avif::AvifDecoder::new(fin)?.dimensions(),
        #[cfg(feature = "jpeg")]
        image::ImageFormat::Jpeg => jpeg::JpegDecoder::new(fin)?.dimensions(),
        #[cfg(feature = "png")]
        image::ImageFormat::Png => png::PngDecoder::new(fin)?.dimensions(),
        #[cfg(feature = "gif")]
        image::ImageFormat::Gif => gif::GifDecoder::new(fin)?.dimensions(),
        #[cfg(feature = "webp")]
        image::ImageFormat::WebP => webp::WebPDecoder::new(fin)?.dimensions(),
        #[cfg(feature = "tiff")]
        image::ImageFormat::Tiff => tiff::TiffDecoder::new(fin)?.dimensions(),
        #[cfg(feature = "tga")]
        image::ImageFormat::Tga => tga::TgaDecoder::new(fin)?.dimensions(),
        #[cfg(feature = "dds")]
        image::ImageFormat::Dds => dds::DdsDecoder::new(fin)?.dimensions(),
        #[cfg(feature = "bmp")]
        image::ImageFormat::Bmp => bmp::BmpDecoder::new(fin)?.dimensions(),
        #[cfg(feature = "ico")]
        image::ImageFormat::Ico => ico::IcoDecoder::new(fin)?.dimensions(),
        #[cfg(feature = "hdr")]
        image::ImageFormat::Hdr => hdr::HdrAdapter::new(fin)?.dimensions(),
        #[cfg(feature = "openexr")]
        image::ImageFormat::OpenExr => openexr::OpenExrDecoder::new(fin)?.dimensions(),
        #[cfg(feature = "pnm")]
        image::ImageFormat::Pnm => {
            pnm::PnmDecoder::new(fin)?.dimensions()
        }
        format => return Err(ImageError::Unsupported(ImageFormatHint::Exact(format).into())),
    })
}

#[allow(unused_variables)]
// Most variables when no features are supported
pub(crate) fn save_buffer_impl(
    path: &Path,
    buf: &[u8],
    width: u32,
    height: u32,
    color: color::ColorType,
) -> ImageResult<()> {
    let fout = &mut BufWriter::new(File::create(path)?);
    let format =  ImageFormat::from_path(path)?;
    save_buffer_with_format_impl(path, buf, width, height, color, format)
}

#[allow(unused_variables)]
// Most variables when no features are supported
pub(crate) fn save_buffer_with_format_impl(
    path: &Path,
    buf: &[u8],
    width: u32,
    height: u32,
    color: color::ColorType,
    format: ImageFormat,
) -> ImageResult<()> {
    let fout = &mut BufWriter::new(File::create(path)?);

    let format = match format {
        #[cfg(feature = "pnm")]
        image::ImageFormat::Pnm => {
            let ext = path.extension()
            .and_then(|s| s.to_str())
            .map_or("".to_string(), |s| s.to_ascii_lowercase());
            ImageOutputFormat::Pnm(match &*ext {
                "pbm" => pnm::PNMSubtype::Bitmap(pnm::SampleEncoding::Binary),
                "pgm" => pnm::PNMSubtype::Graymap(pnm::SampleEncoding::Binary),
                "ppm" => pnm::PNMSubtype::Pixmap(pnm::SampleEncoding::Binary),
                _ => { return Err(ImageError::Unsupported(ImageFormatHint::Exact(format).into())) }, // Unsupported Pnm subtype.
            })
        },
        // #[cfg(feature = "hdr")]
        // image::ImageFormat::Hdr => hdr::HdrEncoder::new(fout).encode(&[Rgb<f32>], width, height), // usize
        #[cfg(feature = "tiff")]
        image::ImageFormat::Tiff => {
            return tiff::TiffEncoder::new(fout).write_image(buf, width, height, color);
        },
        format => format.into(),
    };

    write_buffer_impl(fout, buf, width, height, color, format)
}

#[allow(unused_variables)]
// Most variables when no features are supported
pub(crate) fn write_buffer_impl<W: std::io::Write>(
    fout: &mut W,
    buf: &[u8],
    width: u32,
    height: u32,
    color: color::ColorType,
    format: ImageOutputFormat,
) -> ImageResult<()> {
    match format {
        #[cfg(feature = "png")]
        ImageOutputFormat::Png => png::PngEncoder::new(fout).write_image(buf, width, height, color),
        #[cfg(feature = "jpeg")]
        ImageOutputFormat::Jpeg(quality) => jpeg::JpegEncoder::new_with_quality(fout, quality)
            .write_image(buf, width, height, color),
        #[cfg(feature = "pnm")]
        ImageOutputFormat::Pnm(subtype) => pnm::PnmEncoder::new(fout)
            .with_subtype(subtype)
            .write_image(buf, width, height, color),
        #[cfg(feature = "gif")]
        ImageOutputFormat::Gif => gif::GifEncoder::new(fout).encode(buf, width, height, color),
        #[cfg(feature = "ico")]
        ImageOutputFormat::Ico => ico::IcoEncoder::new(fout).write_image(buf, width, height, color),
        #[cfg(feature = "bmp")]
        ImageOutputFormat::Bmp => bmp::BmpEncoder::new(fout).write_image(buf, width, height, color),
        #[cfg(feature = "farbfeld")]
        ImageOutputFormat::Farbfeld => farbfeld::FarbfeldEncoder::new(fout).write_image(buf, width, height, color),
        #[cfg(feature = "tga")]
        ImageOutputFormat::Tga => tga::TgaEncoder::new(fout).write_image(buf, width, height, color),
        #[cfg(feature = "openexr")]
        ImageOutputFormat::OpenExr => openexr::OpenExrEncoder::new(fout).write_image(buf, width, height, color),
        #[cfg(feature = "tiff")]
        ImageOutputFormat::Tiff => {
            let mut cursor = std::io::Cursor::new(Vec::new());
            tiff::TiffEncoder::new(&mut cursor).write_image(buf, width, height, color)?;
            fout.write(&cursor.into_inner()[..])
                .map(|_| ())
                .map_err(ImageError::IoError)
        }
        #[cfg(feature = "avif-encoder")]
        ImageOutputFormat::Avif => avif::AvifEncoder::new(fout).write_image(buf, width, height, color),

        image::ImageOutputFormat::Unsupported(msg) => {
            Err(ImageError::Unsupported(UnsupportedError::from_format_and_kind(
                ImageFormatHint::Unknown,
                UnsupportedErrorKind::Format(ImageFormatHint::Name(msg)))))
        }

        image::ImageOutputFormat::__NonExhaustive(marker) => match marker._private {},

    }
}

static MAGIC_BYTES: [(&[u8], ImageFormat); 21] = [
    (b"\x89PNG\r\n\x1a\n", ImageFormat::Png),
    (&[0xff, 0xd8, 0xff], ImageFormat::Jpeg),
    (b"GIF89a", ImageFormat::Gif),
    (b"GIF87a", ImageFormat::Gif),
    (b"RIFF", ImageFormat::WebP), // TODO: better magic byte detection, see https://github.com/image-rs/image/issues/660
    (b"MM\x00*", ImageFormat::Tiff),
    (b"II*\x00", ImageFormat::Tiff),
    (b"DDS ", ImageFormat::Dds),
    (b"BM", ImageFormat::Bmp),
    (&[0, 0, 1, 0], ImageFormat::Ico),
    (b"#?RADIANCE", ImageFormat::Hdr),
    (b"P1", ImageFormat::Pnm),
    (b"P2", ImageFormat::Pnm),
    (b"P3", ImageFormat::Pnm),
    (b"P4", ImageFormat::Pnm),
    (b"P5", ImageFormat::Pnm),
    (b"P6", ImageFormat::Pnm),
    (b"P7", ImageFormat::Pnm),
    (b"farbfeld", ImageFormat::Farbfeld),
    (b"\0\0\0 ftypavif", ImageFormat::Avif),
    (&[0x76, 0x2f, 0x31, 0x01], ImageFormat::OpenExr), // = &exr::meta::magic_number::BYTES
];

/// Guess image format from memory block
///
/// Makes an educated guess about the image format based on the Magic Bytes at the beginning.
/// TGA is not supported by this function.
/// This is not to be trusted on the validity of the whole memory block
pub fn guess_format(buffer: &[u8]) -> ImageResult<ImageFormat> {
    match guess_format_impl(buffer) {
        Some(format) => Ok(format),
        None => Err(ImageError::Unsupported(ImageFormatHint::Unknown.into())),
    }
}

pub(crate) fn guess_format_impl(buffer: &[u8]) -> Option<ImageFormat> {
    for &(signature, format) in &MAGIC_BYTES {
        if buffer.starts_with(signature) {
            return Some(format);
        }
    }

    None
}
<commit_msg>File path is now checked before creating file on save<commit_after>use std::fs::File;
use std::io::{BufRead, BufReader, BufWriter, Seek};
use std::path::Path;
use std::u32;

use crate::codecs::*;

use crate::{ImageOutputFormat, color, error::{UnsupportedError, UnsupportedErrorKind}};
use crate::image;
use crate::dynimage::DynamicImage;
use crate::error::{ImageError, ImageFormatHint, ImageResult};
use crate::image::ImageFormat;
#[allow(unused_imports)]  // When no features are supported
use crate::image::{ImageDecoder, ImageEncoder};

pub(crate) fn open_impl(path: &Path) -> ImageResult<DynamicImage> {
    let fin = match File::open(path) {
        Ok(f) => f,
        Err(err) => return Err(ImageError::IoError(err)),
    };
    let fin = BufReader::new(fin);

    load(fin, ImageFormat::from_path(path)?)
}

/// Create a new image from a Reader.
///
/// Assumes the reader is already buffered. For optimal performance,
/// consider wrapping the reader with a `BufRead::new()`.
///
/// Try [`io::Reader`] for more advanced uses.
///
/// [`io::Reader`]: io/struct.Reader.html
#[allow(unused_variables)]
// r is unused if no features are supported.
pub fn load<R: BufRead + Seek>(r: R, format: ImageFormat) -> ImageResult<DynamicImage> {
    #[allow(unreachable_patterns)]
    // Default is unreachable if all features are supported.
    match format {
        #[cfg(feature = "avif-decoder")]
        image::ImageFormat::Avif => DynamicImage::from_decoder(avif::AvifDecoder::new(r)?),
        #[cfg(feature = "png")]
        image::ImageFormat::Png => DynamicImage::from_decoder(png::PngDecoder::new(r)?),
        #[cfg(feature = "gif")]
        image::ImageFormat::Gif => DynamicImage::from_decoder(gif::GifDecoder::new(r)?),
        #[cfg(feature = "jpeg")]
        image::ImageFormat::Jpeg => DynamicImage::from_decoder(jpeg::JpegDecoder::new(r)?),
        #[cfg(feature = "webp")]
        image::ImageFormat::WebP => DynamicImage::from_decoder(webp::WebPDecoder::new(r)?),
        #[cfg(feature = "tiff")]
        image::ImageFormat::Tiff => DynamicImage::from_decoder(tiff::TiffDecoder::new(r)?),
        #[cfg(feature = "tga")]
        image::ImageFormat::Tga => DynamicImage::from_decoder(tga::TgaDecoder::new(r)?),
        #[cfg(feature = "dds")]
        image::ImageFormat::Dds => DynamicImage::from_decoder(dds::DdsDecoder::new(r)?),
        #[cfg(feature = "bmp")]
        image::ImageFormat::Bmp => DynamicImage::from_decoder(bmp::BmpDecoder::new(r)?),
        #[cfg(feature = "ico")]
        image::ImageFormat::Ico => DynamicImage::from_decoder(ico::IcoDecoder::new(r)?),
        #[cfg(feature = "hdr")]
        image::ImageFormat::Hdr => DynamicImage::from_decoder(hdr::HdrAdapter::new(BufReader::new(r))?),
        #[cfg(feature = "openexr")]
        image::ImageFormat::OpenExr => DynamicImage::from_decoder(openexr::OpenExrDecoder::new(r)?),
        #[cfg(feature = "pnm")]
        image::ImageFormat::Pnm => DynamicImage::from_decoder(pnm::PnmDecoder::new(BufReader::new(r))?),
        #[cfg(feature = "farbfeld")]
        image::ImageFormat::Farbfeld => DynamicImage::from_decoder(farbfeld::FarbfeldDecoder::new(r)?),
        _ => Err(ImageError::Unsupported(ImageFormatHint::Exact(format).into())),
    }
}

pub(crate) fn image_dimensions_impl(path: &Path) -> ImageResult<(u32, u32)> {
    let format = image::ImageFormat::from_path(path)?;

    let fin = File::open(path)?;
    let fin = BufReader::new(fin);

    image_dimensions_with_format_impl(fin, format)
}

#[allow(unused_variables)]
// fin is unused if no features are supported.
pub(crate) fn image_dimensions_with_format_impl<R: BufRead + Seek>(fin: R, format: ImageFormat)
    -> ImageResult<(u32, u32)>
{
    #[allow(unreachable_patterns,unreachable_code)]
    // Default is unreachable if all features are supported.
    // Code after the match is unreachable if none are.
    Ok(match format {
        #[cfg(feature = "avif-decoder")]
        image::ImageFormat::Avif => avif::AvifDecoder::new(fin)?.dimensions(),
        #[cfg(feature = "jpeg")]
        image::ImageFormat::Jpeg => jpeg::JpegDecoder::new(fin)?.dimensions(),
        #[cfg(feature = "png")]
        image::ImageFormat::Png => png::PngDecoder::new(fin)?.dimensions(),
        #[cfg(feature = "gif")]
        image::ImageFormat::Gif => gif::GifDecoder::new(fin)?.dimensions(),
        #[cfg(feature = "webp")]
        image::ImageFormat::WebP => webp::WebPDecoder::new(fin)?.dimensions(),
        #[cfg(feature = "tiff")]
        image::ImageFormat::Tiff => tiff::TiffDecoder::new(fin)?.dimensions(),
        #[cfg(feature = "tga")]
        image::ImageFormat::Tga => tga::TgaDecoder::new(fin)?.dimensions(),
        #[cfg(feature = "dds")]
        image::ImageFormat::Dds => dds::DdsDecoder::new(fin)?.dimensions(),
        #[cfg(feature = "bmp")]
        image::ImageFormat::Bmp => bmp::BmpDecoder::new(fin)?.dimensions(),
        #[cfg(feature = "ico")]
        image::ImageFormat::Ico => ico::IcoDecoder::new(fin)?.dimensions(),
        #[cfg(feature = "hdr")]
        image::ImageFormat::Hdr => hdr::HdrAdapter::new(fin)?.dimensions(),
        #[cfg(feature = "openexr")]
        image::ImageFormat::OpenExr => openexr::OpenExrDecoder::new(fin)?.dimensions(),
        #[cfg(feature = "pnm")]
        image::ImageFormat::Pnm => {
            pnm::PnmDecoder::new(fin)?.dimensions()
        }
        format => return Err(ImageError::Unsupported(ImageFormatHint::Exact(format).into())),
    })
}

#[allow(unused_variables)]
// Most variables when no features are supported
pub(crate) fn save_buffer_impl(
    path: &Path,
    buf: &[u8],
    width: u32,
    height: u32,
    color: color::ColorType,
) -> ImageResult<()> {
    let format =  ImageFormat::from_path(path)?;
    let fout = &mut BufWriter::new(File::create(path)?);
    save_buffer_with_format_impl(path, buf, width, height, color, format)
}

#[allow(unused_variables)]
// Most variables when no features are supported
pub(crate) fn save_buffer_with_format_impl(
    path: &Path,
    buf: &[u8],
    width: u32,
    height: u32,
    color: color::ColorType,
    format: ImageFormat,
) -> ImageResult<()> {
    let fout = &mut BufWriter::new(File::create(path)?);

    let format = match format {
        #[cfg(feature = "pnm")]
        image::ImageFormat::Pnm => {
            let ext = path.extension()
            .and_then(|s| s.to_str())
            .map_or("".to_string(), |s| s.to_ascii_lowercase());
            ImageOutputFormat::Pnm(match &*ext {
                "pbm" => pnm::PNMSubtype::Bitmap(pnm::SampleEncoding::Binary),
                "pgm" => pnm::PNMSubtype::Graymap(pnm::SampleEncoding::Binary),
                "ppm" => pnm::PNMSubtype::Pixmap(pnm::SampleEncoding::Binary),
                _ => { return Err(ImageError::Unsupported(ImageFormatHint::Exact(format).into())) }, // Unsupported Pnm subtype.
            })
        },
        // #[cfg(feature = "hdr")]
        // image::ImageFormat::Hdr => hdr::HdrEncoder::new(fout).encode(&[Rgb<f32>], width, height), // usize
        #[cfg(feature = "tiff")]
        image::ImageFormat::Tiff => {
            return tiff::TiffEncoder::new(fout).write_image(buf, width, height, color);
        },
        format => format.into(),
    };

    write_buffer_impl(fout, buf, width, height, color, format)
}

#[allow(unused_variables)]
// Most variables when no features are supported
pub(crate) fn write_buffer_impl<W: std::io::Write>(
    fout: &mut W,
    buf: &[u8],
    width: u32,
    height: u32,
    color: color::ColorType,
    format: ImageOutputFormat,
) -> ImageResult<()> {
    match format {
        #[cfg(feature = "png")]
        ImageOutputFormat::Png => png::PngEncoder::new(fout).write_image(buf, width, height, color),
        #[cfg(feature = "jpeg")]
        ImageOutputFormat::Jpeg(quality) => jpeg::JpegEncoder::new_with_quality(fout, quality)
            .write_image(buf, width, height, color),
        #[cfg(feature = "pnm")]
        ImageOutputFormat::Pnm(subtype) => pnm::PnmEncoder::new(fout)
            .with_subtype(subtype)
            .write_image(buf, width, height, color),
        #[cfg(feature = "gif")]
        ImageOutputFormat::Gif => gif::GifEncoder::new(fout).encode(buf, width, height, color),
        #[cfg(feature = "ico")]
        ImageOutputFormat::Ico => ico::IcoEncoder::new(fout).write_image(buf, width, height, color),
        #[cfg(feature = "bmp")]
        ImageOutputFormat::Bmp => bmp::BmpEncoder::new(fout).write_image(buf, width, height, color),
        #[cfg(feature = "farbfeld")]
        ImageOutputFormat::Farbfeld => farbfeld::FarbfeldEncoder::new(fout).write_image(buf, width, height, color),
        #[cfg(feature = "tga")]
        ImageOutputFormat::Tga => tga::TgaEncoder::new(fout).write_image(buf, width, height, color),
        #[cfg(feature = "openexr")]
        ImageOutputFormat::OpenExr => openexr::OpenExrEncoder::new(fout).write_image(buf, width, height, color),
        #[cfg(feature = "tiff")]
        ImageOutputFormat::Tiff => {
            let mut cursor = std::io::Cursor::new(Vec::new());
            tiff::TiffEncoder::new(&mut cursor).write_image(buf, width, height, color)?;
            fout.write(&cursor.into_inner()[..])
                .map(|_| ())
                .map_err(ImageError::IoError)
        }
        #[cfg(feature = "avif-encoder")]
        ImageOutputFormat::Avif => avif::AvifEncoder::new(fout).write_image(buf, width, height, color),

        image::ImageOutputFormat::Unsupported(msg) => {
            Err(ImageError::Unsupported(UnsupportedError::from_format_and_kind(
                ImageFormatHint::Unknown,
                UnsupportedErrorKind::Format(ImageFormatHint::Name(msg)))))
        }

        image::ImageOutputFormat::__NonExhaustive(marker) => match marker._private {},

    }
}

static MAGIC_BYTES: [(&[u8], ImageFormat); 21] = [
    (b"\x89PNG\r\n\x1a\n", ImageFormat::Png),
    (&[0xff, 0xd8, 0xff], ImageFormat::Jpeg),
    (b"GIF89a", ImageFormat::Gif),
    (b"GIF87a", ImageFormat::Gif),
    (b"RIFF", ImageFormat::WebP), // TODO: better magic byte detection, see https://github.com/image-rs/image/issues/660
    (b"MM\x00*", ImageFormat::Tiff),
    (b"II*\x00", ImageFormat::Tiff),
    (b"DDS ", ImageFormat::Dds),
    (b"BM", ImageFormat::Bmp),
    (&[0, 0, 1, 0], ImageFormat::Ico),
    (b"#?RADIANCE", ImageFormat::Hdr),
    (b"P1", ImageFormat::Pnm),
    (b"P2", ImageFormat::Pnm),
    (b"P3", ImageFormat::Pnm),
    (b"P4", ImageFormat::Pnm),
    (b"P5", ImageFormat::Pnm),
    (b"P6", ImageFormat::Pnm),
    (b"P7", ImageFormat::Pnm),
    (b"farbfeld", ImageFormat::Farbfeld),
    (b"\0\0\0 ftypavif", ImageFormat::Avif),
    (&[0x76, 0x2f, 0x31, 0x01], ImageFormat::OpenExr), // = &exr::meta::magic_number::BYTES
];

/// Guess image format from memory block
///
/// Makes an educated guess about the image format based on the Magic Bytes at the beginning.
/// TGA is not supported by this function.
/// This is not to be trusted on the validity of the whole memory block
pub fn guess_format(buffer: &[u8]) -> ImageResult<ImageFormat> {
    match guess_format_impl(buffer) {
        Some(format) => Ok(format),
        None => Err(ImageError::Unsupported(ImageFormatHint::Unknown.into())),
    }
}

pub(crate) fn guess_format_impl(buffer: &[u8]) -> Option<ImageFormat> {
    for &(signature, format) in &MAGIC_BYTES {
        if buffer.starts_with(signature) {
            return Some(format);
        }
    }

    None
}
<|endoftext|>


<commit_before>use super::node::read_unchecked;
use super::node::write_node;
use super::node::NodeWriteGuard;
use super::search::MutSearchResult;
use super::LevelTree;
use super::NodeCellRef;
use super::*;
use super::BPlusTree;
use itertools::Itertools;
use std::fmt::Debug;

pub const LEVEL_PAGE_DIFF_MULTIPLIER: usize = 4;
pub const LEVEL_TREE_DEPTH: u32 = 2;

pub const LEVEL_M: usize = 16; // Smaller can be faster but more fragmented
pub const LEVEL_1: usize = LEVEL_M * LEVEL_PAGE_DIFF_MULTIPLIER;
pub const LEVEL_2: usize = LEVEL_1 * LEVEL_PAGE_DIFF_MULTIPLIER;

pub const NUM_LEVELS: usize = 3;

fn merge_prune<KS, PS>(
    level: usize,
    node: &NodeCellRef,
    src_tree: &BPlusTree<KS, PS>,
    dest_tree: &dyn LevelTree,
    boundary: &EntryKey
) -> usize
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    let search = mut_first::<KS, PS>(node);
    match search {
        MutSearchResult::External => {
            let nodes = select_nodes_in_boundary::<KS, PS>(node, boundary);
            // Collect keys to merge
            let all_keys = nodes.iter().map(|n| n.keys()).flatten().cloned().collect_vec();
            let mut deleted_keys = Vec::with_capacity(all_keys.len());
            let mut merging_keys = Vec::with_capacity(all_keys.len());
            all_keys.iter().for_each(|k| {
                if src_tree.deleted.contains(k) {
                    deleted_keys.push(k);
                } else {
                    merging_keys.push(k.clone());
                }
            });
            let num_keys_merging = merging_keys.len();
            // Merging with destination tree
            dest_tree.merge_with_keys(box merging_keys);
            // Update delete set in source
            for dk in deleted_keys { src_tree.deleted.remove(dk); }
            let first_node_id = nodes[0].extnode().id;
            // Cut tree in external level
            let mut new_first_node = clear_nodes(nodes);
            // Reset first node. We don't want to update the tree head id so we will reuse the id
            let ext_node = new_first_node.extnode_mut(src_tree);
            ext_node.prev = Default::default();
            ext_node.id = first_node_id;
            return num_keys_merging;
        }
        MutSearchResult::Internal(sub_node) => {
            let num_keys_merged = merge_prune(level + 1, &sub_node, src_tree, dest_tree, boundary);
            if level > 0 {
                let nodes = select_nodes_in_boundary::<KS, PS>(node, boundary);
                clear_nodes(nodes);
            } else {
                let mut node = write_node::<KS, PS>(node);
                debug_assert!(node.right_ref().unwrap().is_default()); // Ensure the root is still the root, not splitted
                // Find the boundary in the root and remove all keys and ptrs to there
                let bound_id = node.keys().binary_search(boundary).unwrap();
                let mut new_keys = KS::init();
                let mut new_ptrs = PS::init();
                let mut num_keys = 0;
                for (i, k) in node.keys()[bound_id + 1..].iter().enumerate() {
                    new_keys.as_slice()[i] = k.clone();
                    num_keys += 1;
                }
                for (i, p) in node.ptrs()[bound_id + 1..].iter().enumerate() {
                    new_ptrs.as_slice()[i] = p.clone();
                }
                let root_innode = node.innode_mut();
                root_innode.keys = new_keys;
                root_innode.ptrs = new_ptrs;
                root_innode.len = num_keys;
            }
            return num_keys_merged;
        }
    }
}

fn clear_nodes<KS, PS>(nodes: Vec<NodeWriteGuard<KS, PS>>) -> NodeWriteGuard<KS, PS>
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    let num_nodes = nodes.len();
    let mut right_node = None;
    for (i, mut node) in nodes.into_iter().enumerate() {
        if i == num_nodes {
            right_node = Some(write_node(node.right_ref().unwrap()));
        };
        node.make_empty_node(false);
    }
    right_node.unwrap()
}

fn select_nodes_in_boundary<KS, PS>(first_node: &NodeCellRef, right_boundary: &EntryKey) -> Vec<NodeWriteGuard<KS, PS>>
 where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    trace!("Acquiring first node");
    let first_node = write_node(first_node);
    assert!(
        read_unchecked::<KS, PS>(first_node.left_ref().unwrap()).is_none(),
        "Left most is not none, have {}",
        read_unchecked::<KS, PS>(first_node.left_ref().unwrap()).type_name()
    );
    let mut next_node = write_node(first_node.right_ref().unwrap());
    let mut collected = vec![first_node];
    loop {
        debug_assert!(next_node.first_key() < right_boundary);
        debug_assert!(next_node.right_bound() <= right_boundary);
        let next_right = write_node(next_node.right_ref().unwrap());
        collected.push(next_node);
        next_node = next_right;
        if next_node.first_key() < right_boundary {
            break;
        }
    }
    collected
}

fn select_boundary_from_root<KS, PS>(root: &NodeCellRef) -> EntryKey
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    read_node(root, |root_node: &NodeReadHandler<KS, PS>| {
        debug_assert!(root_node.is_internal()); // It should be but not mandatory
        let node_keys = root_node.keys();
        let node_len = node_keys.len();
        debug_assert!(node_len > 2); // Must have enough keys in the root
        // Pick half of the keys in the root
        // Genreally, higher level sub tree in LSM tree will select more keys to merged
        // into next level
        let mid_idx = node_len / 2;
        // Return the mid key as the boundary for selection (cut)
        node_keys[mid_idx].clone()
    })
}

pub async fn level_merge<KS, PS>(
    level: usize,
    src_tree: &BPlusTree<KS, PS>,
    dest_tree: &dyn LevelTree,
) -> usize
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    debug!("Merging LSM tree level {}", level);
    let root = src_tree.get_root();
    let key_boundary = select_boundary_from_root::<KS, PS>(&root);
    let num_keys = merge_prune(0, &src_tree.get_root(), src_tree, dest_tree, &key_boundary);
    debug_assert!(verification::tree_has_no_empty_node(&src_tree));
    debug_assert!(verification::is_tree_in_order(&src_tree, level));
    debug!("Merge and pruned level {}, waiting for storage", level);
    storage::wait_until_updated().await;
    debug!("MERGE LEVEL {} COMPLETED", level);
    return num_keys;
}
<commit_msg>fixed boundary handeling<commit_after>use super::node::read_unchecked;
use super::node::write_node;
use super::node::NodeWriteGuard;
use super::search::MutSearchResult;
use super::LevelTree;
use super::NodeCellRef;
use super::*;
use super::BPlusTree;
use itertools::Itertools;
use std::fmt::Debug;

pub const LEVEL_PAGE_DIFF_MULTIPLIER: usize = 4;
pub const LEVEL_TREE_DEPTH: u32 = 2;

pub const LEVEL_M: usize = 16; // Smaller can be faster but more fragmented
pub const LEVEL_1: usize = LEVEL_M * LEVEL_PAGE_DIFF_MULTIPLIER;
pub const LEVEL_2: usize = LEVEL_1 * LEVEL_PAGE_DIFF_MULTIPLIER;

pub const NUM_LEVELS: usize = 3;

fn merge_prune<KS, PS>(
    level: usize,
    node: &NodeCellRef,
    src_tree: &BPlusTree<KS, PS>,
    dest_tree: &dyn LevelTree,
    boundary: &EntryKey
) -> usize
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    let search = mut_first::<KS, PS>(node);
    match search {
        MutSearchResult::External => {
            let (mut nodes, mut new_first) = select_nodes_in_boundary::<KS, PS>(node, boundary);
            // Collect keys to merge
            let all_keys = nodes.iter().map(|n| n.keys()).flatten().cloned().collect_vec();
            let mut deleted_keys = Vec::with_capacity(all_keys.len());
            let mut merging_keys = Vec::with_capacity(all_keys.len());
            all_keys.iter().for_each(|k| {
                if src_tree.deleted.contains(k) {
                    deleted_keys.push(k);
                } else {
                    merging_keys.push(k.clone());
                }
            });
            let num_keys_merging = merging_keys.len();
            // Merging with destination tree
            dest_tree.merge_with_keys(box merging_keys);
            // Update delete set in source
            for dk in deleted_keys { src_tree.deleted.remove(dk); }
            let first_node_id = nodes[0].extnode().id;
            // Cut tree in external level
            clear_nodes(&mut nodes);
            // Reset first node. We don't want to update the tree head id so we will reuse the id
            let ext_node = new_first.extnode_mut(src_tree);
            ext_node.id = first_node_id;
            ext_node.prev = Default::default();
            return num_keys_merging;
        }
        MutSearchResult::Internal(sub_node) => {
            let num_keys_merged = merge_prune(level + 1, &sub_node, src_tree, dest_tree, boundary);
            if level > 0 {
                let (mut nodes, _) = select_nodes_in_boundary::<KS, PS>(node, boundary);
                clear_nodes(&mut nodes);
            } else {
                let mut node = write_node::<KS, PS>(node);
                debug_assert!(node.right_ref().unwrap().is_default()); // Ensure the root is still the root, not splitted
                // Find the boundary in the root and remove all keys and ptrs to there
                let bound_id = node.keys().binary_search(boundary).unwrap();
                let mut new_keys = KS::init();
                let mut new_ptrs = PS::init();
                let mut num_keys = 0;
                for (i, k) in node.keys()[bound_id + 1..].iter().enumerate() {
                    new_keys.as_slice()[i] = k.clone();
                    num_keys += 1;
                }
                for (i, p) in node.ptrs()[bound_id + 1..].iter().enumerate() {
                    new_ptrs.as_slice()[i] = p.clone();
                }
                let root_innode = node.innode_mut();
                root_innode.keys = new_keys;
                root_innode.ptrs = new_ptrs;
                root_innode.len = num_keys;
            }
            return num_keys_merged;
        }
    }
}

fn clear_nodes<KS, PS>(nodes: &mut Vec<NodeWriteGuard<KS, PS>>)
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    for node in nodes.iter_mut() {
        node.make_empty_node(false);
    }
}

fn select_nodes_in_boundary<KS, PS>(first_node: &NodeCellRef, right_boundary: &EntryKey) -> (Vec<NodeWriteGuard<KS, PS>>, NodeWriteGuard<KS, PS>)
 where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    trace!("Acquiring first node");
    let first_node = write_node(first_node);
    let mut next_node = write_node(first_node.right_ref().unwrap());
    let mut collected = vec![first_node];
    loop {
        debug_assert!(next_node.first_key() < right_boundary);
        debug_assert!(next_node.right_bound() <= right_boundary);
        let next_right = write_node(next_node.right_ref().unwrap());
        collected.push(next_node);
        next_node = next_right;
        if next_node.first_key() >= right_boundary {
            return (collected, next_node)
        }
    }
}

fn select_boundary_from_root<KS, PS>(root: &NodeCellRef) -> EntryKey
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    read_node(root, |root_node: &NodeReadHandler<KS, PS>| {
        debug_assert!(root_node.is_internal()); // It should be but not mandatory
        let node_keys = root_node.keys();
        let node_len = node_keys.len();
        debug_assert!(node_len > 2); // Must have enough keys in the root
        // Pick half of the keys in the root
        // Genreally, higher level sub tree in LSM tree will select more keys to merged
        // into next level
        let mid_idx = node_len / 2;
        // Return the mid key as the boundary for selection (cut)
        node_keys[mid_idx].clone()
    })
}

pub async fn level_merge<KS, PS>(
    level: usize,
    src_tree: &BPlusTree<KS, PS>,
    dest_tree: &dyn LevelTree,
) -> usize
where
    KS: Slice<EntryKey> + Debug + 'static,
    PS: Slice<NodeCellRef> + 'static,
{
    debug!("Merging LSM tree level {}", level);
    debug_assert!(verification::tree_has_no_empty_node(&src_tree));
    debug_assert!(verification::is_tree_in_order(&src_tree, level));
    let root = src_tree.get_root();
    let key_boundary = select_boundary_from_root::<KS, PS>(&root);
    let num_keys = merge_prune(0, &src_tree.get_root(), src_tree, dest_tree, &key_boundary);
    debug_assert!(verification::tree_has_no_empty_node(&src_tree));
    debug_assert!(verification::is_tree_in_order(&src_tree, level));
    debug!("Merge and pruned level {}, waiting for storage", level);
    storage::wait_until_updated().await;
    debug!("MERGE LEVEL {} COMPLETED", level);
    return num_keys;
}
<|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.

use borrow::{Borrow, Cow, ToOwned};
use ffi::CString;
use fmt::{self, Debug};
use mem;
use string::String;
use ops;
use cmp;
use hash::{Hash, Hasher};
use vec::Vec;

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

/// Owned, mutable OS strings.
#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct OsString {
    inner: Buf
}

/// Slices into OS strings.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct OsStr {
    inner: Slice
}

impl OsString {
    /// Constructs a new empty `OsString`.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn new() -> OsString {
        OsString { inner: Buf::from_string(String::new()) }
    }

    /// Constructs an `OsString` from a byte sequence.
    ///
    /// # Platform behavior
    ///
    /// On Unix systems, any byte sequence can be successfully
    /// converted into an `OsString`.
    ///
    /// On Windows system, only UTF-8 byte sequences will successfully
    /// convert; non UTF-8 data will produce `None`.
    #[unstable(feature = "convert", reason = "recently added", issue = "27704")]
    #[rustc_deprecated(reason = "RFC was closed, hides subtle Windows semantics",
                       since = "1.6.0")]
    pub fn from_bytes<B>(bytes: B) -> Option<OsString> where B: Into<Vec<u8>> {
        Self::_from_bytes(bytes.into())
    }

    #[cfg(unix)]
    fn _from_bytes(vec: Vec<u8>) -> Option<OsString> {
        use os::unix::ffi::OsStringExt;
        Some(OsString::from_vec(vec))
    }

    #[cfg(windows)]
    fn _from_bytes(vec: Vec<u8>) -> Option<OsString> {
        String::from_utf8(vec).ok().map(OsString::from)
    }

    /// Converts to an `OsStr` slice.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn as_os_str(&self) -> &OsStr {
        self
    }

    /// Converts the `OsString` into a `String` if it contains valid Unicode data.
    ///
    /// On failure, ownership of the original `OsString` is returned.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn into_string(self) -> Result<String, OsString> {
        self.inner.into_string().map_err(|buf| OsString { inner: buf} )
    }

    /// Extends the string with the given `&OsStr` slice.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn push<T: AsRef<OsStr>>(&mut self, s: T) {
        self.inner.push_slice(&s.as_ref().inner)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl From<String> for OsString {
    fn from(s: String) -> OsString {
        OsString { inner: Buf::from_string(s) }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized + AsRef<OsStr>> From<&'a T> for OsString {
    fn from(s: &'a T) -> OsString {
        s.as_ref().to_os_string()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::RangeFull> for OsString {
    type Output = OsStr;

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

#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Deref for OsString {
    type Target = OsStr;

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

#[stable(feature = "rust1", since = "1.0.0")]
impl Debug for OsString {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        fmt::Debug::fmt(&**self, formatter)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for OsString {
    fn eq(&self, other: &OsString) -> bool {
        &**self == &**other
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<str> for OsString {
    fn eq(&self, other: &str) -> bool {
        &**self == other
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<OsString> for str {
    fn eq(&self, other: &OsString) -> bool {
        &**other == self
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Eq for OsString {}

#[stable(feature = "rust1", since = "1.0.0")]
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 }
}

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

#[stable(feature = "rust1", since = "1.0.0")]
impl Ord for OsString {
    #[inline]
    fn cmp(&self, other: &OsString) -> cmp::Ordering {
        (&**self).cmp(&**other)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Hash for OsString {
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        (&**self).hash(state)
    }
}

impl OsStr {
    /// Coerces into an `OsStr` slice.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
        s.as_ref()
    }

    fn from_inner(inner: &Slice) -> &OsStr {
        unsafe { mem::transmute(inner) }
    }

    /// Yields a `&str` slice if the `OsStr` is valid unicode.
    ///
    /// This conversion may entail doing a check for UTF-8 validity.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn to_str(&self) -> Option<&str> {
        self.inner.to_str()
    }

    /// Converts an `OsStr` to a `Cow<str>`.
    ///
    /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn to_string_lossy(&self) -> Cow<str> {
        self.inner.to_string_lossy()
    }

    /// Copies the slice into an owned `OsString`.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn to_os_string(&self) -> OsString {
        OsString { inner: self.inner.to_owned() }
    }

    /// Yields this `OsStr` as a byte slice.
    ///
    /// # Platform behavior
    ///
    /// On Unix systems, this is a no-op.
    ///
    /// On Windows systems, this returns `None` unless the `OsStr` is
    /// valid unicode, in which case it produces UTF-8-encoded
    /// data. This may entail checking validity.
    #[unstable(feature = "convert", reason = "recently added", issue = "27704")]
    #[rustc_deprecated(reason = "RFC was closed, hides subtle Windows semantics",
                       since = "1.6.0")]
    pub fn to_bytes(&self) -> Option<&[u8]> {
        if cfg!(windows) {
            self.to_str().map(|s| s.as_bytes())
        } else {
            Some(self.bytes())
        }
    }

    /// Creates a `CString` containing this `OsStr` data.
    ///
    /// Fails if the `OsStr` contains interior nulls.
    ///
    /// This is a convenience for creating a `CString` from
    /// `self.to_bytes()`, and inherits the platform behavior of the
    /// `to_bytes` method.
    #[unstable(feature = "convert", reason = "recently added", issue = "27704")]
    #[rustc_deprecated(reason = "RFC was closed, hides subtle Windows semantics",
                       since = "1.6.0")]
    #[allow(deprecated)]
    pub fn to_cstring(&self) -> Option<CString> {
        self.to_bytes().and_then(|b| CString::new(b).ok())
    }

    /// Gets 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) }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for OsStr {
    fn eq(&self, other: &OsStr) -> bool {
        self.bytes().eq(other.bytes())
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<str> for OsStr {
    fn eq(&self, other: &str) -> bool {
        *self == *OsStr::new(other)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<OsStr> for str {
    fn eq(&self, other: &OsStr) -> bool {
        *other == *OsStr::new(self)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Eq for OsStr {}

#[stable(feature = "rust1", since = "1.0.0")]
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()) }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd<str> for OsStr {
    #[inline]
    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
        self.partial_cmp(OsStr::new(other))
    }
}

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

#[stable(feature = "rust1", since = "1.0.0")]
impl Ord for OsStr {
    #[inline]
    fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Hash for OsStr {
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.bytes().hash(state)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Debug for OsStr {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.inner.fmt(formatter)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Borrow<OsStr> for OsString {
    fn borrow(&self) -> &OsStr { &self[..] }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl ToOwned for OsStr {
    type Owned = OsString;
    fn to_owned(&self) -> OsString { self.to_os_string() }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for OsStr {
    fn as_ref(&self) -> &OsStr {
        self
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for OsString {
    fn as_ref(&self) -> &OsStr {
        self
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for str {
    fn as_ref(&self) -> &OsStr {
        OsStr::from_inner(Slice::from_str(self))
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for String {
    fn as_ref(&self) -> &OsStr {
        (&**self).as_ref()
    }
}

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>Move os_str docs to OsString in order to be visible in HTML (fixes #30743)<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.

use borrow::{Borrow, Cow, ToOwned};
use ffi::CString;
use fmt::{self, Debug};
use mem;
use string::String;
use ops;
use cmp;
use hash::{Hash, Hasher};
use vec::Vec;

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

/// A type that can represent owned, mutable 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.
///
/// `OsString` and `OsStr` 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.
#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct OsString {
    inner: Buf
}

/// Slices into OS strings (see `OsString`).
#[stable(feature = "rust1", since = "1.0.0")]
pub struct OsStr {
    inner: Slice
}

impl OsString {
    /// Constructs a new empty `OsString`.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn new() -> OsString {
        OsString { inner: Buf::from_string(String::new()) }
    }

    /// Constructs an `OsString` from a byte sequence.
    ///
    /// # Platform behavior
    ///
    /// On Unix systems, any byte sequence can be successfully
    /// converted into an `OsString`.
    ///
    /// On Windows system, only UTF-8 byte sequences will successfully
    /// convert; non UTF-8 data will produce `None`.
    #[unstable(feature = "convert", reason = "recently added", issue = "27704")]
    #[rustc_deprecated(reason = "RFC was closed, hides subtle Windows semantics",
                       since = "1.6.0")]
    pub fn from_bytes<B>(bytes: B) -> Option<OsString> where B: Into<Vec<u8>> {
        Self::_from_bytes(bytes.into())
    }

    #[cfg(unix)]
    fn _from_bytes(vec: Vec<u8>) -> Option<OsString> {
        use os::unix::ffi::OsStringExt;
        Some(OsString::from_vec(vec))
    }

    #[cfg(windows)]
    fn _from_bytes(vec: Vec<u8>) -> Option<OsString> {
        String::from_utf8(vec).ok().map(OsString::from)
    }

    /// Converts to an `OsStr` slice.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn as_os_str(&self) -> &OsStr {
        self
    }

    /// Converts the `OsString` into a `String` if it contains valid Unicode data.
    ///
    /// On failure, ownership of the original `OsString` is returned.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn into_string(self) -> Result<String, OsString> {
        self.inner.into_string().map_err(|buf| OsString { inner: buf} )
    }

    /// Extends the string with the given `&OsStr` slice.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn push<T: AsRef<OsStr>>(&mut self, s: T) {
        self.inner.push_slice(&s.as_ref().inner)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl From<String> for OsString {
    fn from(s: String) -> OsString {
        OsString { inner: Buf::from_string(s) }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized + AsRef<OsStr>> From<&'a T> for OsString {
    fn from(s: &'a T) -> OsString {
        s.as_ref().to_os_string()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::RangeFull> for OsString {
    type Output = OsStr;

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

#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Deref for OsString {
    type Target = OsStr;

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

#[stable(feature = "rust1", since = "1.0.0")]
impl Debug for OsString {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        fmt::Debug::fmt(&**self, formatter)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for OsString {
    fn eq(&self, other: &OsString) -> bool {
        &**self == &**other
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<str> for OsString {
    fn eq(&self, other: &str) -> bool {
        &**self == other
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<OsString> for str {
    fn eq(&self, other: &OsString) -> bool {
        &**other == self
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Eq for OsString {}

#[stable(feature = "rust1", since = "1.0.0")]
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 }
}

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

#[stable(feature = "rust1", since = "1.0.0")]
impl Ord for OsString {
    #[inline]
    fn cmp(&self, other: &OsString) -> cmp::Ordering {
        (&**self).cmp(&**other)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Hash for OsString {
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        (&**self).hash(state)
    }
}

impl OsStr {
    /// Coerces into an `OsStr` slice.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
        s.as_ref()
    }

    fn from_inner(inner: &Slice) -> &OsStr {
        unsafe { mem::transmute(inner) }
    }

    /// Yields a `&str` slice if the `OsStr` is valid unicode.
    ///
    /// This conversion may entail doing a check for UTF-8 validity.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn to_str(&self) -> Option<&str> {
        self.inner.to_str()
    }

    /// Converts an `OsStr` to a `Cow<str>`.
    ///
    /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn to_string_lossy(&self) -> Cow<str> {
        self.inner.to_string_lossy()
    }

    /// Copies the slice into an owned `OsString`.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn to_os_string(&self) -> OsString {
        OsString { inner: self.inner.to_owned() }
    }

    /// Yields this `OsStr` as a byte slice.
    ///
    /// # Platform behavior
    ///
    /// On Unix systems, this is a no-op.
    ///
    /// On Windows systems, this returns `None` unless the `OsStr` is
    /// valid unicode, in which case it produces UTF-8-encoded
    /// data. This may entail checking validity.
    #[unstable(feature = "convert", reason = "recently added", issue = "27704")]
    #[rustc_deprecated(reason = "RFC was closed, hides subtle Windows semantics",
                       since = "1.6.0")]
    pub fn to_bytes(&self) -> Option<&[u8]> {
        if cfg!(windows) {
            self.to_str().map(|s| s.as_bytes())
        } else {
            Some(self.bytes())
        }
    }

    /// Creates a `CString` containing this `OsStr` data.
    ///
    /// Fails if the `OsStr` contains interior nulls.
    ///
    /// This is a convenience for creating a `CString` from
    /// `self.to_bytes()`, and inherits the platform behavior of the
    /// `to_bytes` method.
    #[unstable(feature = "convert", reason = "recently added", issue = "27704")]
    #[rustc_deprecated(reason = "RFC was closed, hides subtle Windows semantics",
                       since = "1.6.0")]
    #[allow(deprecated)]
    pub fn to_cstring(&self) -> Option<CString> {
        self.to_bytes().and_then(|b| CString::new(b).ok())
    }

    /// Gets 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) }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for OsStr {
    fn eq(&self, other: &OsStr) -> bool {
        self.bytes().eq(other.bytes())
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<str> for OsStr {
    fn eq(&self, other: &str) -> bool {
        *self == *OsStr::new(other)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq<OsStr> for str {
    fn eq(&self, other: &OsStr) -> bool {
        *other == *OsStr::new(self)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Eq for OsStr {}

#[stable(feature = "rust1", since = "1.0.0")]
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()) }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl PartialOrd<str> for OsStr {
    #[inline]
    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
        self.partial_cmp(OsStr::new(other))
    }
}

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

#[stable(feature = "rust1", since = "1.0.0")]
impl Ord for OsStr {
    #[inline]
    fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Hash for OsStr {
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.bytes().hash(state)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Debug for OsStr {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.inner.fmt(formatter)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Borrow<OsStr> for OsString {
    fn borrow(&self) -> &OsStr { &self[..] }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl ToOwned for OsStr {
    type Owned = OsString;
    fn to_owned(&self) -> OsString { self.to_os_string() }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for OsStr {
    fn as_ref(&self) -> &OsStr {
        self
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for OsString {
    fn as_ref(&self) -> &OsStr {
        self
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for str {
    fn as_ref(&self) -> &OsStr {
        OsStr::from_inner(Slice::from_str(self))
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for String {
    fn as_ref(&self) -> &OsStr {
        (&**self).as_ref()
    }
}

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|>