<commit_before>// Copyright 2015 Till Höppner
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![feature(slice_patterns)]

#[macro_use]
extern crate log;
extern crate ilc_base;

use std::io::{BufRead, Write};
use std::borrow::ToOwned;
use std::iter::Iterator;

use ilc_base::event::{Event, Time, Type};
use ilc_base::{Context, Decode, Encode};
use ilc_base::format::{rejoin, strip_one};

use log::LogLevel::Info;

pub struct Weechat;

static TIME_DATE_FORMAT: &'static str = "%Y-%m-%d %H:%M:%S";

pub struct Iter<'a> {
    context: &'a Context,
    input: &'a mut BufRead,
    buffer: Vec<u8>,
}

impl<'a> Iterator for Iter<'a> {
    type Item = ilc_base::Result<Event<'a>>;
    fn next(&mut self) -> Option<ilc_base::Result<Event<'a>>> {
        fn parse_time(c: &Context, date: &str, time: &str) -> Time {
            Time::from_format(&c.timezone, &format!("{} {}", date, time), TIME_DATE_FORMAT)
        }

        loop {
            self.buffer.clear();
            match self.input.read_until(b'\n', &mut self.buffer) {
                Ok(0) | Err(_) => return None,
                Ok(_) => (),
            }

            let buffer = String::from_utf8_lossy(&self.buffer);

            let mut split_tokens: Vec<char> = Vec::new();
            let tokens = buffer.split(|c: char| {
                                   if c.is_whitespace() {
                                       split_tokens.push(c);
                                       true
                                   } else {
                                       false
                                   }
                               })
                               .collect::<Vec<_>>();

            if log_enabled!(Info) {
                info!("Original:  `{}`", buffer);
                info!("Parsing:   {:?}", tokens);
            }

            match &tokens[..tokens.len() - 1] {
                [date, time, "-->", nick, host, "has", "joined", channel, _..] => {
                    return Some(Ok(Event {
                        ty: Type::Join {
                            nick: nick.to_owned().into(),
                            mask: Some(strip_one(host).into()),
                        },
                        channel: Some(channel.to_owned().into()),
                        time: parse_time(&self.context, date, time),
                    }))
                }
                [date, time, "<--", nick, host, "has", "left", channel, reason..] => {
                    return Some(Ok(Event {
                        ty: Type::Part {
                            nick: nick.to_owned().into(),
                            mask: Some(strip_one(host).into()),
                            reason: Some(strip_one(&rejoin(reason, &split_tokens[8..])).into()),
                        },
                        channel: Some(channel.to_owned().into()),
                        time: parse_time(&self.context, date, time),
                    }))
                }
                [date, time, "<--", nick, host, "has", "quit", reason..] => {
                    return Some(Ok(Event {
                        ty: Type::Quit {
                            nick: nick.to_owned().into(),
                            mask: Some(strip_one(host).into()),
                            reason: Some(strip_one(&rejoin(reason, &split_tokens[7..])).into()),
                        },
                        time: parse_time(&self.context, date, time),
                        channel: self.context.channel.clone().map(Into::into),
                    }))
                }
                [date, time, "--", notice, content..] if notice.starts_with("Notice(") => {
                    return Some(Ok(Event {
                        ty: Type::Notice {
                            from: notice["Notice(".len()..notice.len() - 2].to_owned().into(),
                            content: rejoin(content, &split_tokens[4..]),
                        },
                        time: parse_time(&self.context, date, time),
                        channel: self.context.channel.clone().map(Into::into),
                    }))
                }
                [date, time, "--", "irc:", "disconnected", "from", "server", _..] => {
                    return Some(Ok(Event {
                        ty: Type::Disconnect,
                        time: parse_time(&self.context, date, time),
                        channel: self.context.channel.clone().map(Into::into),
                    }))
                }
                [date, time, "--", nick, verb, "now", "known", "as", new_nick] if verb == "is" ||
                                                                                verb == "are" => {
                    return Some(Ok(Event {
                        ty: Type::Nick {
                            old_nick: nick.to_owned().into(),
                            new_nick: new_nick.to_owned().into(),
                        },
                        time: parse_time(&self.context, date, time),
                        channel: self.context.channel.clone().map(Into::into),
                    }))
                }
                [date, time, sp, "*", nick, msg..] if sp.clone().is_empty() => {
                    return Some(Ok(Event {
                        ty: Type::Action {
                            from: nick.to_owned().into(),
                            content: rejoin(msg, &split_tokens[5..]),
                        },
                        time: parse_time(&self.context, date, time),
                        channel: self.context.channel.clone().map(Into::into),
                    }))
                }
                [date, time, nick, msg..] => {
                    return Some(Ok(Event {
                        ty: Type::Msg {
                            from: nick.to_owned().into(),
                            content: rejoin(msg, &split_tokens[3..]),
                        },
                        time: parse_time(&self.context, date, time),
                        channel: self.context.channel.clone().map(Into::into),
                    }))
                }
                _ => (),
            }
        }
    }
}

impl Decode for Weechat {
    fn decode<'a>(&'a mut self,
                  context: &'a Context,
                  input: &'a mut BufRead)
                  -> Box<Iterator<Item = ilc_base::Result<Event<'a>>> + 'a> {
        Box::new(Iter {
            context: context,
            input: input,
            buffer: Vec::new(),
        })
    }
}

impl Encode for Weechat {
    fn encode<'a>(&'a self,
                  context: &'a Context,
                  mut output: &'a mut Write,
                  event: &'a Event)
                  -> ilc_base::Result<()> {
        match event {
            &Event { ty: Type::Msg { ref from, ref content, .. }, ref time, .. } => {
                try!(writeln!(&mut output,
                              "{}\t{}\t{}",
                              time.with_format(&context.timezone, TIME_DATE_FORMAT),
                              from,
                              content))
            }
            &Event { ty: Type::Action { ref from, ref content, .. }, ref time, .. } => {
                try!(writeln!(&mut output,
                              "{}\t *\t{} {}",
                              time.with_format(&context.timezone, TIME_DATE_FORMAT),
                              from,
                              content))
            }
            &Event { ty: Type::Join { ref nick, ref mask, .. }, ref channel, ref time } => {
                try!(writeln!(&mut output,
                              "{}\t-->\t{} ({}) has joined {}",
                              time.with_format(&context.timezone, TIME_DATE_FORMAT),
                              nick,
                              mask.as_ref().expect("Hostmask not present, but required."),
                              channel.as_ref().expect("Channel not present, but required.")))
            }
            &Event { ty: Type::Part { ref nick, ref mask, ref reason }, ref channel, ref time } => {
                try!(write!(&mut output,
                            "{}\t<--\t{} ({}) has left {}",
                            time.with_format(&context.timezone, TIME_DATE_FORMAT),
                            nick,
                            mask.as_ref().expect("Hostmask not present, but required."),
                            channel.as_ref().expect("Channel not present, but required.")));
                if reason.is_some() && reason.as_ref().unwrap().len() > 0 {
                    try!(write!(&mut output, " ({})", reason.as_ref().unwrap()));
                }
                try!(write!(&mut output, "\n"))
            }
            &Event { ty: Type::Quit { ref nick, ref mask, ref reason }, ref time, .. } => {
                try!(write!(&mut output,
                            "{}\t<--\t{} ({}) has quit",
                            time.with_format(&context.timezone, TIME_DATE_FORMAT),
                            nick,
                            mask.as_ref().expect("Hostmask not present, but required.")));
                if reason.is_some() && reason.as_ref().unwrap().len() > 0 {
                    try!(write!(&mut output, " ({})", reason.as_ref().unwrap()));
                }
                try!(write!(&mut output, "\n"))
            }
            &Event { ty: Type::Disconnect, ref time, .. } => {
                try!(writeln!(&mut output,
                              "{}\t--\tirc: disconnected from server",
                              time.with_format(&context.timezone, TIME_DATE_FORMAT)))
            }
            &Event { ty: Type::Notice { ref from, ref content }, ref time, .. } => {
                try!(writeln!(&mut output,
                              "{}\t--\tNotice({}): {}",
                              time.with_format(&context.timezone, TIME_DATE_FORMAT),
                              from,
                              content))
            }
            _ => (),
        }
        Ok(())
    }
}
<commit_msg>Rewrite slice_pattern part of weechat without slice_pattern<commit_after>// Copyright 2015 Till Höppner
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[macro_use]
extern crate log;
extern crate ilc_base;

use std::io::{BufRead, Write};
use std::borrow::ToOwned;
use std::iter::Iterator;

use ilc_base::event::{Event, Time, Type};
use ilc_base::{Context, Decode, Encode};
use ilc_base::format::{rejoin, strip_one};

use log::LogLevel::Info;

pub struct Weechat;

static TIME_DATE_FORMAT: &'static str = "%Y-%m-%d %H:%M:%S";

pub struct Iter<'a> {
    context: &'a Context,
    input: &'a mut BufRead,
    buffer: Vec<u8>,
}

impl<'a> Iterator for Iter<'a> {
    type Item = ilc_base::Result<Event<'a>>;
    fn next(&mut self) -> Option<ilc_base::Result<Event<'a>>> {
        fn parse_time(c: &Context, date: &str, time: &str) -> Time {
            Time::from_format(&c.timezone, &format!("{} {}", date, time), TIME_DATE_FORMAT)
        }

        loop {
            self.buffer.clear();
            match self.input.read_until(b'\n', &mut self.buffer) {
                Ok(0) | Err(_) => return None,
                Ok(_) => (),
            }

            let buffer = String::from_utf8_lossy(&self.buffer);

            let mut split_tokens: Vec<char> = Vec::new();
            let tokens = buffer.split(|c: char| {
                                   if c.is_whitespace() {
                                       split_tokens.push(c);
                                       true
                                   } else {
                                       false
                                   }
                               })
                               .collect::<Vec<_>>();

            if log_enabled!(Info) {
                info!("Original:  `{}`", buffer);
                info!("Parsing:   {:?}", tokens);
            }

            // slice pattern matching is not stable as of Feb. 2016 and was replaced with
            // nested if-else chains in this module.

            // Don't match on the --> arrows, those are apparently often configured, and
            // that would break parsing for many users.

            if tokens[5] == "has" {
                // 2016-02-25 01:15:05 --> Foo (host@mask.foo) has joined #example
                if tokens[6] == "joined" {
                    return Some(Ok(Event {
                        ty: Type::Join {
                            nick: tokens[3].to_owned().into(),
                            mask: Some(strip_one(tokens[4]).into()),
                        },
                        channel: Some(tokens[7].to_owned().into()),
                        time: parse_time(&self.context, tokens[0], tokens[1]),
                    }));
                }
                // 2016-02-25 01:36:13 <-- Foo (host@mask.foo) has left #channel (Some reason)
                else if tokens[6] == "left" {
                    return Some(Ok(Event {
                        ty: Type::Part {
                            nick: tokens[3].to_owned().into(),
                            mask: Some(strip_one(&tokens[4]).into()),
                            reason: Some(strip_one(&rejoin(&tokens[8..], &split_tokens[8..]))
                                             .into()),
                        },
                        channel: Some(tokens[7].to_owned().into()),
                        time: parse_time(&self.context, tokens[0], tokens[1]),
                    }));
                }
                // 2016-02-25 01:38:55 <-- Foo (host@mask.foo) has quit (Some reason)
                else if tokens[6] == "quit" {
                    return Some(Ok(Event {
                        ty: Type::Quit {
                            nick: tokens[3].to_owned().into(),
                            mask: Some(strip_one(tokens[4]).into()),
                            reason: Some(strip_one(&rejoin(&tokens[7..], &split_tokens[7..]))
                                             .into()),
                        },
                        time: parse_time(&self.context, tokens[0], tokens[1]),
                        channel: self.context.channel.clone().map(Into::into),
                    }));
                }
            } else if tokens[2] == "--" {
                // 2016-02-25 04:32:15	--	Notice(playbot-veno): ""
                if tokens[3].starts_with("Notice(") {
                    return Some(Ok(Event {
                        ty: Type::Notice {
                            from: tokens[3]["Notice(".len()..tokens.len() - 2].to_owned().into(),
                            content: rejoin(&tokens[4..], &split_tokens[4..]),
                        },
                        time: parse_time(&self.context, tokens[0], tokens[1]),
                        channel: self.context.channel.clone().map(Into::into),
                    }));
                }
                // 2014-07-11 15:00:03	--	irc: disconnected from server
                else if tokens[3] == "irc:" && tokens[4] == "disconnected" && tokens[5] == "from" &&
                   tokens[6] == "server" {
                    return Some(Ok(Event {
                        ty: Type::Disconnect,
                        time: parse_time(&self.context, tokens[0], tokens[1]),
                        channel: self.context.channel.clone().map(Into::into),
                    }));
                }
                // 2014-07-11 15:00:03	--	Foo|afk is now known as Foo
                // 2015-05-09 13:56:05	--	You are now known as foo
                else if tokens[5] == "now" && tokens[6] == "known" && tokens[7] == "as" &&
                   (tokens[4] == "is" || tokens[4] == "are") {
                    return Some(Ok(Event {
                        ty: Type::Nick {
                            old_nick: tokens[3].to_owned().into(),
                            new_nick: tokens[8].to_owned().into(),
                        },
                        time: parse_time(&self.context, tokens[0], tokens[1]),
                        channel: self.context.channel.clone().map(Into::into),
                    }));
                }
            }
            // 2016-01-24 20:32:57	 *	nick emotes
            else if tokens[3] == "*" && tokens[2].is_empty() {
                return Some(Ok(Event {
                    ty: Type::Action {
                        from: tokens[4].to_owned().into(),
                        content: rejoin(&tokens[5..], &split_tokens[5..]),
                    },
                    time: parse_time(&self.context, tokens[0], tokens[1]),
                    channel: self.context.channel.clone().map(Into::into),
                }));
            }
            // 2016-01-24 20:32:25	nick	just some message
            else {
                return Some(Ok(Event {
                    ty: Type::Msg {
                        from: tokens[2].to_owned().into(),
                        content: rejoin(&tokens[3..], &split_tokens[3..]),
                    },
                    time: parse_time(&self.context, tokens[0], tokens[1]),
                    channel: self.context.channel.clone().map(Into::into),
                }));
            }
        }
    }
}

impl Decode for Weechat {
    fn decode<'a>(&'a mut self,
                  context: &'a Context,
                  input: &'a mut BufRead)
                  -> Box<Iterator<Item = ilc_base::Result<Event<'a>>> + 'a> {
        Box::new(Iter {
            context: context,
            input: input,
            buffer: Vec::new(),
        })
    }
}

impl Encode for Weechat {
    fn encode<'a>(&'a self,
                  context: &'a Context,
                  mut output: &'a mut Write,
                  event: &'a Event)
                  -> ilc_base::Result<()> {
        match event {
            &Event { ty: Type::Msg { ref from, ref content, .. }, ref time, .. } => {
                try!(writeln!(&mut output,
                              "{}\t{}\t{}",
                              time.with_format(&context.timezone, TIME_DATE_FORMAT),
                              from,
                              content))
            }
            &Event { ty: Type::Action { ref from, ref content, .. }, ref time, .. } => {
                try!(writeln!(&mut output,
                              "{}\t *\t{} {}",
                              time.with_format(&context.timezone, TIME_DATE_FORMAT),
                              from,
                              content))
            }
            &Event { ty: Type::Join { ref nick, ref mask, .. }, ref channel, ref time } => {
                try!(writeln!(&mut output,
                              "{}\t-->\t{} ({}) has joined {}",
                              time.with_format(&context.timezone, TIME_DATE_FORMAT),
                              nick,
                              mask.as_ref().expect("Hostmask not present, but required."),
                              channel.as_ref().expect("Channel not present, but required.")))
            }
            &Event { ty: Type::Part { ref nick, ref mask, ref reason }, ref channel, ref time } => {
                try!(write!(&mut output,
                            "{}\t<--\t{} ({}) has left {}",
                            time.with_format(&context.timezone, TIME_DATE_FORMAT),
                            nick,
                            mask.as_ref().expect("Hostmask not present, but required."),
                            channel.as_ref().expect("Channel not present, but required.")));
                if reason.is_some() && reason.as_ref().unwrap().len() > 0 {
                    try!(write!(&mut output, " ({})", reason.as_ref().unwrap()));
                }
                try!(write!(&mut output, "\n"))
            }
            &Event { ty: Type::Quit { ref nick, ref mask, ref reason }, ref time, .. } => {
                try!(write!(&mut output,
                            "{}\t<--\t{} ({}) has quit",
                            time.with_format(&context.timezone, TIME_DATE_FORMAT),
                            nick,
                            mask.as_ref().expect("Hostmask not present, but required.")));
                if reason.is_some() && reason.as_ref().unwrap().len() > 0 {
                    try!(write!(&mut output, " ({})", reason.as_ref().unwrap()));
                }
                try!(write!(&mut output, "\n"))
            }
            &Event { ty: Type::Disconnect, ref time, .. } => {
                try!(writeln!(&mut output,
                              "{}\t--\tirc: disconnected from server",
                              time.with_format(&context.timezone, TIME_DATE_FORMAT)))
            }
            &Event { ty: Type::Notice { ref from, ref content }, ref time, .. } => {
                try!(writeln!(&mut output,
                              "{}\t--\tNotice({}): {}",
                              time.with_format(&context.timezone, TIME_DATE_FORMAT),
                              from,
                              content))
            }
            _ => (),
        }
        Ok(())
    }
}
<|endoftext|>


<commit_before>use {Enum, EnumMap};

use core::iter::{Enumerate, FusedIterator};
use core::marker::PhantomData;
use core::mem::ManuallyDrop;
use core::ptr;
use core::slice;

/// Immutable enum map iterator
///
/// This struct is created by `iter` method or `into_iter` on a reference
/// to `EnumMap`.
///
/// # Examples
///
/// ```
/// #[macro_use]
/// extern crate enum_map;
///
/// #[derive(EnumMap)]
/// enum Example {
///     A,
///     B,
///     C,
/// }
///
/// fn main() {
///     let mut map = enum_map! { Example::A => 3, _ => 0 };
///     assert_eq!(map[Example::A], 3);
///     for (key, &value) in &map {
///         assert_eq!(value, match key {
///             Example::A => 3,
///             _ => 0,
///         });
///     }
/// }
/// ```
#[derive(Debug)]
pub struct Iter<'a, K, V: 'a> {
    _phantom: PhantomData<fn() -> K>,
    iterator: Enumerate<slice::Iter<'a, V>>,
}

impl<'a, K: Enum<V>, V> Iterator for Iter<'a, K, V> {
    type Item = (K, &'a V);
    fn next(&mut self) -> Option<Self::Item> {
        self.iterator
            .next()
            .map(|(index, item)| (K::from_usize(index), item))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iterator.size_hint()
    }
}

impl<'a, K: Enum<V>, V> DoubleEndedIterator for Iter<'a, K, V> {
    fn next_back(&mut self) -> Option<Self::Item> {
        self.iterator
            .next_back()
            .map(|(index, item)| (K::from_usize(index), item))
    }
}

impl<'a, K: Enum<V>, V> ExactSizeIterator for Iter<'a, K, V> {}

impl<'a, K: Enum<V>, V> FusedIterator for Iter<'a, K, V> {}

impl<'a, K: Enum<V>, V> IntoIterator for &'a EnumMap<K, V> {
    type Item = (K, &'a V);
    type IntoIter = Iter<'a, K, V>;
    fn into_iter(self) -> Self::IntoIter {
        Iter {
            _phantom: PhantomData,
            iterator: self.as_slice().iter().enumerate(),
        }
    }
}

/// Mutable map iterator
///
/// This struct is created by `iter_mut` method or `into_iter` on a mutable
/// reference to `EnumMap`.
///
/// # Examples
///
/// ```
/// #[macro_use]
/// extern crate enum_map;
///
/// #[derive(Debug, EnumMap)]
/// enum Example {
///     A,
///     B,
///     C,
/// }
///
/// fn main() {
///     let mut map = enum_map! { Example::A => 3, _ => 0 };
///     for (_, value) in &mut map {
///         *value += 1;
///     }
///     assert_eq!(map, enum_map! { Example::A => 4, _ => 1 });
/// }
/// ```
#[derive(Debug)]
pub struct IterMut<'a, K, V: 'a> {
    _phantom: PhantomData<fn() -> K>,
    iterator: Enumerate<slice::IterMut<'a, V>>,
}

impl<'a, K: Enum<V>, V> Iterator for IterMut<'a, K, V> {
    type Item = (K, &'a mut V);
    fn next(&mut self) -> Option<Self::Item> {
        self.iterator
            .next()
            .map(|(index, item)| (K::from_usize(index), item))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iterator.size_hint()
    }
}

impl<'a, K: Enum<V>, V> DoubleEndedIterator for IterMut<'a, K, V> {
    fn next_back(&mut self) -> Option<Self::Item> {
        self.iterator
            .next_back()
            .map(|(index, item)| (K::from_usize(index), item))
    }
}

impl<'a, K: Enum<V>, V> ExactSizeIterator for IterMut<'a, K, V> {}

impl<'a, K: Enum<V>, V> FusedIterator for IterMut<'a, K, V> {}

impl<'a, K: Enum<V>, V> IntoIterator for &'a mut EnumMap<K, V> {
    type Item = (K, &'a mut V);
    type IntoIter = IterMut<'a, K, V>;
    fn into_iter(self) -> Self::IntoIter {
        IterMut {
            _phantom: PhantomData,
            iterator: self.as_mut_slice().iter_mut().enumerate(),
        }
    }
}

/// A map iterator that moves out of map.
///
/// This struct is created by `into_iter` on `EnumMap`.
///
/// # Examples
///
/// ```
/// #[macro_use]
/// extern crate enum_map;
///
/// #[derive(Debug, EnumMap)]
/// enum Example {
///     A,
///     B,
/// }
///
/// fn main() {
///     let map = enum_map! { Example::A | Example::B => String::from("123") };
///     for (_, value) in map {
///         assert_eq!(value + "4", "1234");
///     }
/// }
/// ```
pub struct IntoIter<K: Enum<V>, V> {
    map: ManuallyDrop<EnumMap<K, V>>,
    position: usize,
}

impl<K: Enum<V>, V> Iterator for IntoIter<K, V> {
    type Item = (K, V);
    fn next(&mut self) -> Option<(K, V)> {
        let slice = self.map.as_slice();
        if self.position < slice.len() {
            let key = K::from_usize(self.position);
            let result = Some((key, unsafe { ptr::read(&slice[self.position]) }));
            self.position += 1;
            result
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let slice = self.map.as_slice();
        let diff = slice.len() - self.position;
        (diff, Some(diff))
    }
}

impl<K: Enum<V>, V> ExactSizeIterator for IntoIter<K, V> {}

impl<K: Enum<V>, V> FusedIterator for IntoIter<K, V> {}

impl<K: Enum<V>, V> Drop for IntoIter<K, V> {
    fn drop(&mut self) {
        for _item in self {}
    }
}

impl<K: Enum<V>, V> IntoIterator for EnumMap<K, V> {
    type Item = (K, V);
    type IntoIter = IntoIter<K, V>;
    fn into_iter(self) -> Self::IntoIter {
        IntoIter {
            map: ManuallyDrop::new(self),
            position: 0,
        }
    }
}

impl<K: Enum<V>, V> EnumMap<K, V> {
    /// An iterator visiting all values. The iterator type is `&V`.
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// fn main() {
    ///     let map = enum_map! { false => 3, true => 4 };
    ///     let mut values = map.values();
    ///     assert_eq!(values.next(), Some(&3));
    ///     assert_eq!(values.next(), Some(&4));
    ///     assert_eq!(values.next(), None);
    /// }
    /// ```
    pub fn values(&self) -> Values<V> {
        Values(self.as_slice().iter())
    }

    /// An iterator visiting all values mutably. The iterator type is `&mut V`.
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// fn main() {
    ///     let mut map = enum_map! { _ => 2 };
    ///     for value in map.values_mut() {
    ///         *value += 2;
    ///     }
    ///     assert_eq!(map[false], 4);
    ///     assert_eq!(map[true], 4);
    /// }
    /// ```
    pub fn values_mut(&mut self) -> ValuesMut<V> {
        ValuesMut(self.as_mut_slice().iter_mut())
    }
}

/// An iterator over the values of `EnumMap`.
///
/// This `struct` is created by the `values` method of `EnumMap`.
/// See its documentation for more.
pub struct Values<'a, V: 'a>(slice::Iter<'a, V>);

impl<'a, V: 'a> Iterator for Values<'a, V> {
    type Item = &'a V;
    fn next(&mut self) -> Option<&'a V> {
        self.0.next()
    }
}

/// A mutable iterator over the values of `EnumMap`.
///
/// This `struct` is created by the `values_mut` method of `EnumMap`.
/// See its documentation for more.
pub struct ValuesMut<'a, V: 'a>(slice::IterMut<'a, V>);

impl<'a, V: 'a> Iterator for ValuesMut<'a, V> {
    type Item = &'a mut V;
    fn next(&mut self) -> Option<&'a mut V> {
        self.0.next()
    }
}
<commit_msg>Implement DoubleEndedIterator for Values structs<commit_after>use {Enum, EnumMap};

use core::iter::{Enumerate, FusedIterator};
use core::marker::PhantomData;
use core::mem::ManuallyDrop;
use core::ptr;
use core::slice;

/// Immutable enum map iterator
///
/// This struct is created by `iter` method or `into_iter` on a reference
/// to `EnumMap`.
///
/// # Examples
///
/// ```
/// #[macro_use]
/// extern crate enum_map;
///
/// #[derive(EnumMap)]
/// enum Example {
///     A,
///     B,
///     C,
/// }
///
/// fn main() {
///     let mut map = enum_map! { Example::A => 3, _ => 0 };
///     assert_eq!(map[Example::A], 3);
///     for (key, &value) in &map {
///         assert_eq!(value, match key {
///             Example::A => 3,
///             _ => 0,
///         });
///     }
/// }
/// ```
#[derive(Debug)]
pub struct Iter<'a, K, V: 'a> {
    _phantom: PhantomData<fn() -> K>,
    iterator: Enumerate<slice::Iter<'a, V>>,
}

impl<'a, K: Enum<V>, V> Iterator for Iter<'a, K, V> {
    type Item = (K, &'a V);
    fn next(&mut self) -> Option<Self::Item> {
        self.iterator
            .next()
            .map(|(index, item)| (K::from_usize(index), item))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iterator.size_hint()
    }
}

impl<'a, K: Enum<V>, V> DoubleEndedIterator for Iter<'a, K, V> {
    fn next_back(&mut self) -> Option<Self::Item> {
        self.iterator
            .next_back()
            .map(|(index, item)| (K::from_usize(index), item))
    }
}

impl<'a, K: Enum<V>, V> ExactSizeIterator for Iter<'a, K, V> {}

impl<'a, K: Enum<V>, V> FusedIterator for Iter<'a, K, V> {}

impl<'a, K: Enum<V>, V> IntoIterator for &'a EnumMap<K, V> {
    type Item = (K, &'a V);
    type IntoIter = Iter<'a, K, V>;
    fn into_iter(self) -> Self::IntoIter {
        Iter {
            _phantom: PhantomData,
            iterator: self.as_slice().iter().enumerate(),
        }
    }
}

/// Mutable map iterator
///
/// This struct is created by `iter_mut` method or `into_iter` on a mutable
/// reference to `EnumMap`.
///
/// # Examples
///
/// ```
/// #[macro_use]
/// extern crate enum_map;
///
/// #[derive(Debug, EnumMap)]
/// enum Example {
///     A,
///     B,
///     C,
/// }
///
/// fn main() {
///     let mut map = enum_map! { Example::A => 3, _ => 0 };
///     for (_, value) in &mut map {
///         *value += 1;
///     }
///     assert_eq!(map, enum_map! { Example::A => 4, _ => 1 });
/// }
/// ```
#[derive(Debug)]
pub struct IterMut<'a, K, V: 'a> {
    _phantom: PhantomData<fn() -> K>,
    iterator: Enumerate<slice::IterMut<'a, V>>,
}

impl<'a, K: Enum<V>, V> Iterator for IterMut<'a, K, V> {
    type Item = (K, &'a mut V);
    fn next(&mut self) -> Option<Self::Item> {
        self.iterator
            .next()
            .map(|(index, item)| (K::from_usize(index), item))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iterator.size_hint()
    }
}

impl<'a, K: Enum<V>, V> DoubleEndedIterator for IterMut<'a, K, V> {
    fn next_back(&mut self) -> Option<Self::Item> {
        self.iterator
            .next_back()
            .map(|(index, item)| (K::from_usize(index), item))
    }
}

impl<'a, K: Enum<V>, V> ExactSizeIterator for IterMut<'a, K, V> {}

impl<'a, K: Enum<V>, V> FusedIterator for IterMut<'a, K, V> {}

impl<'a, K: Enum<V>, V> IntoIterator for &'a mut EnumMap<K, V> {
    type Item = (K, &'a mut V);
    type IntoIter = IterMut<'a, K, V>;
    fn into_iter(self) -> Self::IntoIter {
        IterMut {
            _phantom: PhantomData,
            iterator: self.as_mut_slice().iter_mut().enumerate(),
        }
    }
}

/// A map iterator that moves out of map.
///
/// This struct is created by `into_iter` on `EnumMap`.
///
/// # Examples
///
/// ```
/// #[macro_use]
/// extern crate enum_map;
///
/// #[derive(Debug, EnumMap)]
/// enum Example {
///     A,
///     B,
/// }
///
/// fn main() {
///     let map = enum_map! { Example::A | Example::B => String::from("123") };
///     for (_, value) in map {
///         assert_eq!(value + "4", "1234");
///     }
/// }
/// ```
pub struct IntoIter<K: Enum<V>, V> {
    map: ManuallyDrop<EnumMap<K, V>>,
    position: usize,
}

impl<K: Enum<V>, V> Iterator for IntoIter<K, V> {
    type Item = (K, V);
    fn next(&mut self) -> Option<(K, V)> {
        let slice = self.map.as_slice();
        if self.position < slice.len() {
            let key = K::from_usize(self.position);
            let result = Some((key, unsafe { ptr::read(&slice[self.position]) }));
            self.position += 1;
            result
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let slice = self.map.as_slice();
        let diff = slice.len() - self.position;
        (diff, Some(diff))
    }
}

impl<K: Enum<V>, V> ExactSizeIterator for IntoIter<K, V> {}

impl<K: Enum<V>, V> FusedIterator for IntoIter<K, V> {}

impl<K: Enum<V>, V> Drop for IntoIter<K, V> {
    fn drop(&mut self) {
        for _item in self {}
    }
}

impl<K: Enum<V>, V> IntoIterator for EnumMap<K, V> {
    type Item = (K, V);
    type IntoIter = IntoIter<K, V>;
    fn into_iter(self) -> Self::IntoIter {
        IntoIter {
            map: ManuallyDrop::new(self),
            position: 0,
        }
    }
}

impl<K: Enum<V>, V> EnumMap<K, V> {
    /// An iterator visiting all values. The iterator type is `&V`.
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// fn main() {
    ///     let map = enum_map! { false => 3, true => 4 };
    ///     let mut values = map.values();
    ///     assert_eq!(values.next(), Some(&3));
    ///     assert_eq!(values.next(), Some(&4));
    ///     assert_eq!(values.next(), None);
    /// }
    /// ```
    pub fn values(&self) -> Values<V> {
        Values(self.as_slice().iter())
    }

    /// An iterator visiting all values mutably. The iterator type is `&mut V`.
    ///
    /// # Examples
    ///
    /// ```
    /// #[macro_use]
    /// extern crate enum_map;
    ///
    /// fn main() {
    ///     let mut map = enum_map! { _ => 2 };
    ///     for value in map.values_mut() {
    ///         *value += 2;
    ///     }
    ///     assert_eq!(map[false], 4);
    ///     assert_eq!(map[true], 4);
    /// }
    /// ```
    pub fn values_mut(&mut self) -> ValuesMut<V> {
        ValuesMut(self.as_mut_slice().iter_mut())
    }
}

/// An iterator over the values of `EnumMap`.
///
/// This `struct` is created by the `values` method of `EnumMap`.
/// See its documentation for more.
pub struct Values<'a, V: 'a>(slice::Iter<'a, V>);

impl<'a, V: 'a> Iterator for Values<'a, V> {
    type Item = &'a V;
    fn next(&mut self) -> Option<&'a V> {
        self.0.next()
    }
}

impl<'a, V: 'a> DoubleEndedIterator for Values<'a, V> {
    fn next_back(&mut self) -> Option<&'a V> {
        self.0.next_back()
    }
}

/// A mutable iterator over the values of `EnumMap`.
///
/// This `struct` is created by the `values_mut` method of `EnumMap`.
/// See its documentation for more.
pub struct ValuesMut<'a, V: 'a>(slice::IterMut<'a, V>);

impl<'a, V: 'a> Iterator for ValuesMut<'a, V> {
    type Item = &'a mut V;
    fn next(&mut self) -> Option<&'a mut V> {
        self.0.next()
    }
}

impl<'a, V: 'a> DoubleEndedIterator for ValuesMut<'a, V> {
    fn next_back(&mut self) -> Option<&'a mut V> {
        self.0.next_back()
    }
}
<|endoftext|>


<commit_before>//! Types and traits related to serializing values for the database

use std::error::Error;
use std::fmt;
use std::io::{self, Write};
use std::result;

use crate::backend::{Backend, HasBindCollector};
use crate::query_builder::bind_collector::RawBytesBindCollector;
use crate::query_builder::BindCollector;

#[cfg(feature = "postgres_backend")]
pub use crate::pg::serialize::*;

/// A specialized result type representing the result of serializing
/// a value for the database.
pub type Result = result::Result<IsNull, Box<dyn Error + Send + Sync>>;

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
/// Tiny enum to make the return type of `ToSql` more descriptive
pub enum IsNull {
    /// No data was written, as this type is null
    Yes,
    /// The value is not null
    ///
    /// This does not necessarily mean that any data was written to the buffer.
    /// For example, an empty string has no data to be sent over the wire, but
    /// also is not null.
    No,
}

/// Wraps a buffer to be written by `ToSql` with additional backend specific
/// utilities.
pub struct Output<'a, 'b, DB>
where
    DB: Backend,
    DB::MetadataLookup: 'a,
{
    out: <crate::backend::BindCollector<'a, DB> as BindCollector<'a, DB>>::Buffer,
    metadata_lookup: Option<&'b mut DB::MetadataLookup>,
}

impl<'a, 'b, DB: Backend> Output<'a, 'b, DB> {
    /// Construct a new `Output`
    pub fn new(
        out: <crate::backend::BindCollector<'a, DB> as BindCollector<'a, DB>>::Buffer,
        metadata_lookup: &'b mut DB::MetadataLookup,
    ) -> Self {
        Output {
            out,
            metadata_lookup: Some(metadata_lookup),
        }
    }

    #[cfg(feature = "sqlite")]
    pub(crate) fn into_inner(
        self,
    ) -> <crate::backend::BindCollector<'a, DB> as BindCollector<'a, DB>>::Buffer {
        self.out
    }

    /// Returns the backend's mechanism for dynamically looking up type
    /// metadata at runtime, if relevant for the given backend.
    pub fn metadata_lookup(&mut self) -> &mut DB::MetadataLookup {
        *self.metadata_lookup.as_mut().expect("Lookup is there")
    }
}

#[cfg(feature = "sqlite")]
impl<'a, 'b> Output<'a, 'b, crate::sqlite::Sqlite> {
    pub(crate) fn set_small_int(&mut self, i: i16) {
        self.out = crate::sqlite::SqliteBindValue::I32(i as i32);
    }

    pub(crate) fn set_int(&mut self, i: i32) {
        self.out = crate::sqlite::SqliteBindValue::I32(i);
    }

    pub(crate) fn set_big_int(&mut self, i: i64) {
        self.out = crate::sqlite::SqliteBindValue::I64(i);
    }

    pub(crate) fn set_float(&mut self, i: f32) {
        self.out = crate::sqlite::SqliteBindValue::F64(i as f64);
    }

    pub(crate) fn set_double(&mut self, i: f64) {
        self.out = crate::sqlite::SqliteBindValue::F64(i);
    }

    pub(crate) fn set_borrowed_string(&mut self, s: &'a str) {
        self.out = crate::sqlite::SqliteBindValue::BorrowedString(s);
    }

    pub(crate) fn set_borrowed_binary(&mut self, s: &'a [u8]) {
        self.out = crate::sqlite::SqliteBindValue::BorrowedBinary(s);
    }

    // this can be unused depending on the enabled features
    #[allow(dead_code)]
    pub(crate) fn set_owned_string(&mut self, s: String) {
        self.out = crate::sqlite::SqliteBindValue::String(s.into_boxed_str());
    }

    // This can be unused depending on the enabled features
    #[allow(dead_code)]
    pub(crate) fn set_owned_binary(&mut self, b: Vec<u8>) {
        self.out = crate::sqlite::SqliteBindValue::Binary(b.into_boxed_slice());
    }
}

#[cfg(test)]
impl<'a, DB: Backend> Output<'a, 'static, DB> {
    /// Returns a `Output` suitable for testing `ToSql` implementations.
    /// Unsafe to use for testing types which perform dynamic metadata lookup.
    pub fn test(
        buffer: <crate::backend::BindCollector<'a, DB> as BindCollector<'a, DB>>::Buffer,
    ) -> Self {
        Self {
            out: buffer,
            metadata_lookup: None,
        }
    }
}

impl<'a, 'b, DB: Backend<BindCollector = RawBytesBindCollector<DB>>> Write for Output<'a, 'b, DB> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.out.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.out.flush()
    }

    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        self.out.write_all(buf)
    }

    fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
        self.out.write_fmt(fmt)
    }
}

impl<'a, 'b, DB: Backend<BindCollector = RawBytesBindCollector<DB>>> Output<'a, 'b, DB> {
    /// Call this method whenever you pass an instance of `Output<DB>` by value.
    ///
    /// Effectively copies `self`, with a narrower lifetime. When passing a
    /// reference or a mutable reference, this is normally done by rust
    /// implicitly. This is why you can pass `&mut Foo` to multiple functions,
    /// even though mutable references are not `Copy`. However, this is only
    /// done implicitly for references. For structs with lifetimes it must be
    /// done explicitly. This method matches the semantics of what Rust would do
    /// implicitly if you were passing a mutable reference
    pub fn reborrow<'c>(&'c mut self) -> Output<'c, 'c, DB>
    where
        'a: 'c,
    {
        Output {
            out: RawBytesBindCollector::<DB>::reborrow_buffer(self.out),
            metadata_lookup: match &mut self.metadata_lookup {
                None => None,
                Some(m) => Some(&mut **m),
            },
        }
    }
}

impl<'a, 'b, DB> fmt::Debug for Output<'a, 'b, DB>
where
    <<DB as HasBindCollector<'a>>::BindCollector as BindCollector<'a, DB>>::Buffer: fmt::Debug,
    DB: Backend,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.out.fmt(f)
    }
}

/// Serializes a single value to be sent to the database.
///
/// The output is sent as a bind parameter, and the data must be written in the
/// expected format for the given backend.
///
/// When possible, implementations of this trait should prefer using an existing
/// implementation, rather than writing to `out` directly. (For example, if you
/// are implementing this for an enum, which is represented as an integer in the
/// database, you should use `i32::to_sql(x, out)` instead of writing to `out`
/// yourself.)
///
/// Any types which implement this trait should also
/// [`#[derive(AsExpression)]`](derive@crate::AsExpression).
///
/// ### Backend specific details
///
/// - For PostgreSQL, the bytes will be sent using the binary protocol, not text.
/// - For SQLite, all implementations should be written in terms of an existing
///   `ToSql` implementation.
/// - For MySQL, the expected bytes will depend on the return value of
///   `type_metadata` for the given SQL type. See [`MysqlType`] for details.
/// - For third party backends, consult that backend's documentation.
///
/// [`MysqlType`]: ../mysql/enum.MysqlType.html
///
/// ### Examples
///
/// Most implementations of this trait will be defined in terms of an existing
/// implementation.
///
/// ```rust
/// # use diesel::backend::Backend;
/// # use diesel::expression::AsExpression;
/// # use diesel::sql_types::*;
/// # use diesel::serialize::{self, ToSql, Output};
/// # use std::io::Write;
/// #
/// #[repr(i32)]
/// #[derive(Debug, Clone, Copy, AsExpression)]
/// #[diesel(sql_type = Integer)]
/// pub enum MyEnum {
///     A = 1,
///     B = 2,
/// }
///
/// impl<DB> ToSql<Integer, DB> for MyEnum
/// where
///     DB: Backend,
///     i32: ToSql<Integer, DB>,
/// {
///     fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
///         match self {
///             MyEnum::A => 1.to_sql(out),
///             MyEnum::B => 2.to_sql(out),
///         }
///     }
/// }
/// ```
pub trait ToSql<A, DB: Backend>: fmt::Debug {
    /// See the trait documentation.
    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> Result;
}

impl<'a, A, T, DB> ToSql<A, DB> for &'a T
where
    DB: Backend,
    T: ToSql<A, DB> + ?Sized,
{
    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> Result {
        (*self).to_sql(out)
    }
}
<commit_msg>Fix path for AsExpression derive<commit_after>//! Types and traits related to serializing values for the database

use std::error::Error;
use std::fmt;
use std::io::{self, Write};
use std::result;

use crate::backend::{Backend, HasBindCollector};
use crate::query_builder::bind_collector::RawBytesBindCollector;
use crate::query_builder::BindCollector;

#[cfg(feature = "postgres_backend")]
pub use crate::pg::serialize::*;

/// A specialized result type representing the result of serializing
/// a value for the database.
pub type Result = result::Result<IsNull, Box<dyn Error + Send + Sync>>;

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
/// Tiny enum to make the return type of `ToSql` more descriptive
pub enum IsNull {
    /// No data was written, as this type is null
    Yes,
    /// The value is not null
    ///
    /// This does not necessarily mean that any data was written to the buffer.
    /// For example, an empty string has no data to be sent over the wire, but
    /// also is not null.
    No,
}

/// Wraps a buffer to be written by `ToSql` with additional backend specific
/// utilities.
pub struct Output<'a, 'b, DB>
where
    DB: Backend,
    DB::MetadataLookup: 'a,
{
    out: <crate::backend::BindCollector<'a, DB> as BindCollector<'a, DB>>::Buffer,
    metadata_lookup: Option<&'b mut DB::MetadataLookup>,
}

impl<'a, 'b, DB: Backend> Output<'a, 'b, DB> {
    /// Construct a new `Output`
    pub fn new(
        out: <crate::backend::BindCollector<'a, DB> as BindCollector<'a, DB>>::Buffer,
        metadata_lookup: &'b mut DB::MetadataLookup,
    ) -> Self {
        Output {
            out,
            metadata_lookup: Some(metadata_lookup),
        }
    }

    #[cfg(feature = "sqlite")]
    pub(crate) fn into_inner(
        self,
    ) -> <crate::backend::BindCollector<'a, DB> as BindCollector<'a, DB>>::Buffer {
        self.out
    }

    /// Returns the backend's mechanism for dynamically looking up type
    /// metadata at runtime, if relevant for the given backend.
    pub fn metadata_lookup(&mut self) -> &mut DB::MetadataLookup {
        *self.metadata_lookup.as_mut().expect("Lookup is there")
    }
}

#[cfg(feature = "sqlite")]
impl<'a, 'b> Output<'a, 'b, crate::sqlite::Sqlite> {
    pub(crate) fn set_small_int(&mut self, i: i16) {
        self.out = crate::sqlite::SqliteBindValue::I32(i as i32);
    }

    pub(crate) fn set_int(&mut self, i: i32) {
        self.out = crate::sqlite::SqliteBindValue::I32(i);
    }

    pub(crate) fn set_big_int(&mut self, i: i64) {
        self.out = crate::sqlite::SqliteBindValue::I64(i);
    }

    pub(crate) fn set_float(&mut self, i: f32) {
        self.out = crate::sqlite::SqliteBindValue::F64(i as f64);
    }

    pub(crate) fn set_double(&mut self, i: f64) {
        self.out = crate::sqlite::SqliteBindValue::F64(i);
    }

    pub(crate) fn set_borrowed_string(&mut self, s: &'a str) {
        self.out = crate::sqlite::SqliteBindValue::BorrowedString(s);
    }

    pub(crate) fn set_borrowed_binary(&mut self, s: &'a [u8]) {
        self.out = crate::sqlite::SqliteBindValue::BorrowedBinary(s);
    }

    // this can be unused depending on the enabled features
    #[allow(dead_code)]
    pub(crate) fn set_owned_string(&mut self, s: String) {
        self.out = crate::sqlite::SqliteBindValue::String(s.into_boxed_str());
    }

    // This can be unused depending on the enabled features
    #[allow(dead_code)]
    pub(crate) fn set_owned_binary(&mut self, b: Vec<u8>) {
        self.out = crate::sqlite::SqliteBindValue::Binary(b.into_boxed_slice());
    }
}

#[cfg(test)]
impl<'a, DB: Backend> Output<'a, 'static, DB> {
    /// Returns a `Output` suitable for testing `ToSql` implementations.
    /// Unsafe to use for testing types which perform dynamic metadata lookup.
    pub fn test(
        buffer: <crate::backend::BindCollector<'a, DB> as BindCollector<'a, DB>>::Buffer,
    ) -> Self {
        Self {
            out: buffer,
            metadata_lookup: None,
        }
    }
}

impl<'a, 'b, DB: Backend<BindCollector = RawBytesBindCollector<DB>>> Write for Output<'a, 'b, DB> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.out.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.out.flush()
    }

    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        self.out.write_all(buf)
    }

    fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
        self.out.write_fmt(fmt)
    }
}

impl<'a, 'b, DB: Backend<BindCollector = RawBytesBindCollector<DB>>> Output<'a, 'b, DB> {
    /// Call this method whenever you pass an instance of `Output<DB>` by value.
    ///
    /// Effectively copies `self`, with a narrower lifetime. When passing a
    /// reference or a mutable reference, this is normally done by rust
    /// implicitly. This is why you can pass `&mut Foo` to multiple functions,
    /// even though mutable references are not `Copy`. However, this is only
    /// done implicitly for references. For structs with lifetimes it must be
    /// done explicitly. This method matches the semantics of what Rust would do
    /// implicitly if you were passing a mutable reference
    pub fn reborrow<'c>(&'c mut self) -> Output<'c, 'c, DB>
    where
        'a: 'c,
    {
        Output {
            out: RawBytesBindCollector::<DB>::reborrow_buffer(self.out),
            metadata_lookup: match &mut self.metadata_lookup {
                None => None,
                Some(m) => Some(&mut **m),
            },
        }
    }
}

impl<'a, 'b, DB> fmt::Debug for Output<'a, 'b, DB>
where
    <<DB as HasBindCollector<'a>>::BindCollector as BindCollector<'a, DB>>::Buffer: fmt::Debug,
    DB: Backend,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.out.fmt(f)
    }
}

/// Serializes a single value to be sent to the database.
///
/// The output is sent as a bind parameter, and the data must be written in the
/// expected format for the given backend.
///
/// When possible, implementations of this trait should prefer using an existing
/// implementation, rather than writing to `out` directly. (For example, if you
/// are implementing this for an enum, which is represented as an integer in the
/// database, you should use `i32::to_sql(x, out)` instead of writing to `out`
/// yourself.)
///
/// Any types which implement this trait should also
/// [`#[derive(AsExpression)]`](derive@crate::expression::AsExpression).
///
/// ### Backend specific details
///
/// - For PostgreSQL, the bytes will be sent using the binary protocol, not text.
/// - For SQLite, all implementations should be written in terms of an existing
///   `ToSql` implementation.
/// - For MySQL, the expected bytes will depend on the return value of
///   `type_metadata` for the given SQL type. See [`MysqlType`] for details.
/// - For third party backends, consult that backend's documentation.
///
/// [`MysqlType`]: ../mysql/enum.MysqlType.html
///
/// ### Examples
///
/// Most implementations of this trait will be defined in terms of an existing
/// implementation.
///
/// ```rust
/// # use diesel::backend::Backend;
/// # use diesel::expression::AsExpression;
/// # use diesel::sql_types::*;
/// # use diesel::serialize::{self, ToSql, Output};
/// # use std::io::Write;
/// #
/// #[repr(i32)]
/// #[derive(Debug, Clone, Copy, AsExpression)]
/// #[diesel(sql_type = Integer)]
/// pub enum MyEnum {
///     A = 1,
///     B = 2,
/// }
///
/// impl<DB> ToSql<Integer, DB> for MyEnum
/// where
///     DB: Backend,
///     i32: ToSql<Integer, DB>,
/// {
///     fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> serialize::Result {
///         match self {
///             MyEnum::A => 1.to_sql(out),
///             MyEnum::B => 2.to_sql(out),
///         }
///     }
/// }
/// ```
pub trait ToSql<A, DB: Backend>: fmt::Debug {
    /// See the trait documentation.
    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> Result;
}

impl<'a, A, T, DB> ToSql<A, DB> for &'a T
where
    DB: Backend,
    T: ToSql<A, DB> + ?Sized,
{
    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, DB>) -> Result {
        (*self).to_sql(out)
    }
}
<|endoftext|>


<commit_before>//! Types and traits related to serializing values for the database

use std::error::Error;
use std::fmt;
use std::io::{self, Write};
use std::ops::{Deref, DerefMut};
use std::result;

use crate::backend::Backend;
use crate::sql_types::TypeMetadata;

#[cfg(feature = "postgres")]
pub use crate::pg::serialize::*;

/// A specialized result type representing the result of serializing
/// a value for the database.
pub type Result = result::Result<IsNull, Box<dyn Error + Send + Sync>>;

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
/// Tiny enum to make the return type of `ToSql` more descriptive
pub enum IsNull {
    /// No data was written, as this type is null
    Yes,
    /// The value is not null
    ///
    /// This does not necessarily mean that any data was written to the buffer.
    /// For example, an empty string has no data to be sent over the wire, but
    /// also is not null.
    No,
}

/// Wraps a buffer to be written by `ToSql` with additional backend specific
/// utilities.
pub struct Output<'a, T, DB>
where
    DB: TypeMetadata,
    DB::MetadataLookup: 'a,
{
    out: T,
    metadata_lookup: Option<&'a mut DB::MetadataLookup>,
}

impl<'a, T, DB: TypeMetadata> Output<'a, T, DB> {
    /// Construct a new `Output`
    pub fn new(out: T, metadata_lookup: &'a mut DB::MetadataLookup) -> Self {
        Output {
            out,
            metadata_lookup: Some(metadata_lookup),
        }
    }

    /// Return the raw buffer this type is wrapping
    pub fn into_inner(self) -> T {
        self.out
    }

    /// Returns the backend's mechanism for dynamically looking up type
    /// metadata at runtime, if relevant for the given backend.
    pub fn metadata_lookup(&mut self) -> &mut DB::MetadataLookup {
        *self.metadata_lookup.as_mut().expect("Lookup is there")
    }
}

#[cfg(test)]
impl<DB: TypeMetadata> Output<'static, Vec<u8>, DB> {
    /// Returns a `Output` suitable for testing `ToSql` implementations.
    /// Unsafe to use for testing types which perform dynamic metadata lookup.
    pub fn test() -> Self {
        Self {
            out: Vec::new(),
            metadata_lookup: None,
        }
    }
}

impl<'a, T: Write, DB: TypeMetadata> Write for Output<'a, T, DB> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.out.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.out.flush()
    }

    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        self.out.write_all(buf)
    }

    fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
        self.out.write_fmt(fmt)
    }
}

impl<'a, T, DB: TypeMetadata> Deref for Output<'a, T, DB> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.out
    }
}

impl<'a, T, DB: TypeMetadata> DerefMut for Output<'a, T, DB> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.out
    }
}

impl<'a, T, U, DB> PartialEq<U> for Output<'a, T, DB>
where
    DB: TypeMetadata,
    T: PartialEq<U>,
{
    fn eq(&self, rhs: &U) -> bool {
        self.out == *rhs
    }
}

impl<'a, T, DB> fmt::Debug for Output<'a, T, DB>
where
    T: fmt::Debug,
    DB: TypeMetadata,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.out.fmt(f)
    }
}

/// Serializes a single value to be sent to the database.
///
/// The output is sent as a bind parameter, and the data must be written in the
/// expected format for the given backend.
///
/// When possible, implementations of this trait should prefer using an existing
/// implementation, rather than writing to `out` directly. (For example, if you
/// are implementing this for an enum, which is represented as an integer in the
/// database, you should use `i32::to_sql(x, out)` instead of writing to `out`
/// yourself.
///
/// Any types which implement this trait should also [`#[derive(AsExpression)]`].
///
/// ### Backend specific details
///
/// - For PostgreSQL, the bytes will be sent using the binary protocol, not text.
/// - For SQLite, all implementations should be written in terms of an existing
///   `ToSql` implementation.
/// - For MySQL, the expected bytes will depend on the return value of
///   `type_metadata` for the given SQL type. See [`MysqlType`] for details.
/// - For third party backends, consult that backend's documentation.
///
/// [`MysqlType`]: ../mysql/enum.MysqlType.html
/// [`#[derive(AsExpression)]`]: ../expression/derive.AsExpression.html;
///
/// ### Examples
///
/// Most implementations of this trait will be defined in terms of an existing
/// implementation.
///
/// ```rust
/// # use diesel::backend::Backend;
/// # use diesel::expression::AsExpression;
/// # use diesel::sql_types::*;
/// # use diesel::serialize::{self, ToSql, Output};
/// # use std::io::Write;
/// #
/// #[repr(i32)]
/// #[derive(Debug, Clone, Copy, AsExpression)]
/// #[sql_type = "Integer"]
/// pub enum MyEnum {
///     A = 1,
///     B = 2,
/// }
///
/// impl<DB> ToSql<Integer, DB> for MyEnum
/// where
///     DB: Backend,
///     i32: ToSql<Integer, DB>,
/// {
///     fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> serialize::Result {
///         (*self as i32).to_sql(out)
///     }
/// }
/// ```
pub trait ToSql<A, DB: Backend>: fmt::Debug {
    /// See the trait documentation.
    fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> Result;
}

impl<'a, A, T, DB> ToSql<A, DB> for &'a T
where
    DB: Backend,
    T: ToSql<A, DB> + ?Sized,
{
    fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> Result {
        (*self).to_sql(out)
    }
}
<commit_msg>small typo fix<commit_after>//! Types and traits related to serializing values for the database

use std::error::Error;
use std::fmt;
use std::io::{self, Write};
use std::ops::{Deref, DerefMut};
use std::result;

use crate::backend::Backend;
use crate::sql_types::TypeMetadata;

#[cfg(feature = "postgres")]
pub use crate::pg::serialize::*;

/// A specialized result type representing the result of serializing
/// a value for the database.
pub type Result = result::Result<IsNull, Box<dyn Error + Send + Sync>>;

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
/// Tiny enum to make the return type of `ToSql` more descriptive
pub enum IsNull {
    /// No data was written, as this type is null
    Yes,
    /// The value is not null
    ///
    /// This does not necessarily mean that any data was written to the buffer.
    /// For example, an empty string has no data to be sent over the wire, but
    /// also is not null.
    No,
}

/// Wraps a buffer to be written by `ToSql` with additional backend specific
/// utilities.
pub struct Output<'a, T, DB>
where
    DB: TypeMetadata,
    DB::MetadataLookup: 'a,
{
    out: T,
    metadata_lookup: Option<&'a mut DB::MetadataLookup>,
}

impl<'a, T, DB: TypeMetadata> Output<'a, T, DB> {
    /// Construct a new `Output`
    pub fn new(out: T, metadata_lookup: &'a mut DB::MetadataLookup) -> Self {
        Output {
            out,
            metadata_lookup: Some(metadata_lookup),
        }
    }

    /// Return the raw buffer this type is wrapping
    pub fn into_inner(self) -> T {
        self.out
    }

    /// Returns the backend's mechanism for dynamically looking up type
    /// metadata at runtime, if relevant for the given backend.
    pub fn metadata_lookup(&mut self) -> &mut DB::MetadataLookup {
        *self.metadata_lookup.as_mut().expect("Lookup is there")
    }
}

#[cfg(test)]
impl<DB: TypeMetadata> Output<'static, Vec<u8>, DB> {
    /// Returns a `Output` suitable for testing `ToSql` implementations.
    /// Unsafe to use for testing types which perform dynamic metadata lookup.
    pub fn test() -> Self {
        Self {
            out: Vec::new(),
            metadata_lookup: None,
        }
    }
}

impl<'a, T: Write, DB: TypeMetadata> Write for Output<'a, T, DB> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.out.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.out.flush()
    }

    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
        self.out.write_all(buf)
    }

    fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
        self.out.write_fmt(fmt)
    }
}

impl<'a, T, DB: TypeMetadata> Deref for Output<'a, T, DB> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.out
    }
}

impl<'a, T, DB: TypeMetadata> DerefMut for Output<'a, T, DB> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.out
    }
}

impl<'a, T, U, DB> PartialEq<U> for Output<'a, T, DB>
where
    DB: TypeMetadata,
    T: PartialEq<U>,
{
    fn eq(&self, rhs: &U) -> bool {
        self.out == *rhs
    }
}

impl<'a, T, DB> fmt::Debug for Output<'a, T, DB>
where
    T: fmt::Debug,
    DB: TypeMetadata,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.out.fmt(f)
    }
}

/// Serializes a single value to be sent to the database.
///
/// The output is sent as a bind parameter, and the data must be written in the
/// expected format for the given backend.
///
/// When possible, implementations of this trait should prefer using an existing
/// implementation, rather than writing to `out` directly. (For example, if you
/// are implementing this for an enum, which is represented as an integer in the
/// database, you should use `i32::to_sql(x, out)` instead of writing to `out`
/// yourself.)
///
/// Any types which implement this trait should also [`#[derive(AsExpression)]`].
///
/// ### Backend specific details
///
/// - For PostgreSQL, the bytes will be sent using the binary protocol, not text.
/// - For SQLite, all implementations should be written in terms of an existing
///   `ToSql` implementation.
/// - For MySQL, the expected bytes will depend on the return value of
///   `type_metadata` for the given SQL type. See [`MysqlType`] for details.
/// - For third party backends, consult that backend's documentation.
///
/// [`MysqlType`]: ../mysql/enum.MysqlType.html
/// [`#[derive(AsExpression)]`]: ../expression/derive.AsExpression.html;
///
/// ### Examples
///
/// Most implementations of this trait will be defined in terms of an existing
/// implementation.
///
/// ```rust
/// # use diesel::backend::Backend;
/// # use diesel::expression::AsExpression;
/// # use diesel::sql_types::*;
/// # use diesel::serialize::{self, ToSql, Output};
/// # use std::io::Write;
/// #
/// #[repr(i32)]
/// #[derive(Debug, Clone, Copy, AsExpression)]
/// #[sql_type = "Integer"]
/// pub enum MyEnum {
///     A = 1,
///     B = 2,
/// }
///
/// impl<DB> ToSql<Integer, DB> for MyEnum
/// where
///     DB: Backend,
///     i32: ToSql<Integer, DB>,
/// {
///     fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> serialize::Result {
///         (*self as i32).to_sql(out)
///     }
/// }
/// ```
pub trait ToSql<A, DB: Backend>: fmt::Debug {
    /// See the trait documentation.
    fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> Result;
}

impl<'a, A, T, DB> ToSql<A, DB> for &'a T
where
    DB: Backend,
    T: ToSql<A, DB> + ?Sized,
{
    fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> Result {
        (*self).to_sql(out)
    }
}
<|endoftext|>


<commit_before>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A graph module for use in dataflow, region resolution, and elsewhere.
//!
//! # Interface details
//!
//! You customize the graph by specifying a "node data" type `N` and an
//! "edge data" type `E`. You can then later gain access (mutable or
//! immutable) to these "user-data" bits. Currently, you can only add
//! nodes or edges to the graph. You cannot remove or modify them once
//! added. This could be changed if we have a need.
//!
//! # Implementation details
//!
//! The main tricky thing about this code is the way that edges are
//! stored. The edges are stored in a central array, but they are also
//! threaded onto two linked lists for each node, one for incoming edges
//! and one for outgoing edges. Note that every edge is a member of some
//! incoming list and some outgoing list.  Basically you can load the
//! first index of the linked list from the node data structures (the
//! field `first_edge`) and then, for each edge, load the next index from
//! the field `next_edge`). Each of those fields is an array that should
//! be indexed by the direction (see the type `Direction`).

use bitvec::BitVector;
use std::fmt::{Formatter, Error, Debug};
use std::usize;
use snapshot_vec::{SnapshotVec, SnapshotVecDelegate};

#[cfg(test)]
mod tests;

pub struct Graph<N, E> {
    nodes: SnapshotVec<Node<N>>,
    edges: SnapshotVec<Edge<E>>,
}

pub struct Node<N> {
    first_edge: [EdgeIndex; 2], // see module comment
    pub data: N,
}

pub struct Edge<E> {
    next_edge: [EdgeIndex; 2], // see module comment
    source: NodeIndex,
    target: NodeIndex,
    pub data: E,
}

impl<N> SnapshotVecDelegate for Node<N> {
    type Value = Node<N>;
    type Undo = ();

    fn reverse(_: &mut Vec<Node<N>>, _: ()) {}
}

impl<N> SnapshotVecDelegate for Edge<N> {
    type Value = Edge<N>;
    type Undo = ();

    fn reverse(_: &mut Vec<Edge<N>>, _: ()) {}
}

impl<E: Debug> Debug for Edge<E> {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f,
               "Edge {{ next_edge: [{:?}, {:?}], source: {:?}, target: {:?}, data: {:?} }}",
               self.next_edge[0],
               self.next_edge[1],
               self.source,
               self.target,
               self.data)
    }
}

#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub struct NodeIndex(pub usize);

#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub struct EdgeIndex(pub usize);

pub const INVALID_EDGE_INDEX: EdgeIndex = EdgeIndex(usize::MAX);

// Use a private field here to guarantee no more instances are created:
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Direction {
    repr: usize,
}

pub const OUTGOING: Direction = Direction { repr: 0 };

pub const INCOMING: Direction = Direction { repr: 1 };

impl NodeIndex {
    /// Returns unique id (unique with respect to the graph holding associated node).
    pub fn node_id(&self) -> usize {
        self.0
    }
}

impl EdgeIndex {
    /// Returns unique id (unique with respect to the graph holding associated edge).
    pub fn edge_id(&self) -> usize {
        self.0
    }
}

impl<N: Debug, E: Debug> Graph<N, E> {
    pub fn new() -> Graph<N, E> {
        Graph {
            nodes: SnapshotVec::new(),
            edges: SnapshotVec::new(),
        }
    }

    // # Simple accessors

    #[inline]
    pub fn all_nodes(&self) -> &[Node<N>] {
        &self.nodes
    }

    #[inline]
    pub fn len_nodes(&self) -> usize {
        self.nodes.len()
    }

    #[inline]
    pub fn all_edges(&self) -> &[Edge<E>] {
        &self.edges
    }

    #[inline]
    pub fn len_edges(&self) -> usize {
        self.edges.len()
    }

    // # Node construction

    pub fn next_node_index(&self) -> NodeIndex {
        NodeIndex(self.nodes.len())
    }

    pub fn add_node(&mut self, data: N) -> NodeIndex {
        let idx = self.next_node_index();
        self.nodes.push(Node {
            first_edge: [INVALID_EDGE_INDEX, INVALID_EDGE_INDEX],
            data: data,
        });
        idx
    }

    pub fn mut_node_data(&mut self, idx: NodeIndex) -> &mut N {
        &mut self.nodes[idx.0].data
    }

    pub fn node_data(&self, idx: NodeIndex) -> &N {
        &self.nodes[idx.0].data
    }

    pub fn node(&self, idx: NodeIndex) -> &Node<N> {
        &self.nodes[idx.0]
    }

    // # Edge construction and queries

    pub fn next_edge_index(&self) -> EdgeIndex {
        EdgeIndex(self.edges.len())
    }

    pub fn add_edge(&mut self, source: NodeIndex, target: NodeIndex, data: E) -> EdgeIndex {
        debug!("graph: add_edge({:?}, {:?}, {:?})", source, target, data);

        let idx = self.next_edge_index();

        // read current first of the list of edges from each node
        let source_first = self.nodes[source.0].first_edge[OUTGOING.repr];
        let target_first = self.nodes[target.0].first_edge[INCOMING.repr];

        // create the new edge, with the previous firsts from each node
        // as the next pointers
        self.edges.push(Edge {
            next_edge: [source_first, target_first],
            source: source,
            target: target,
            data: data,
        });

        // adjust the firsts for each node target be the next object.
        self.nodes[source.0].first_edge[OUTGOING.repr] = idx;
        self.nodes[target.0].first_edge[INCOMING.repr] = idx;

        return idx;
    }

    pub fn mut_edge_data(&mut self, idx: EdgeIndex) -> &mut E {
        &mut self.edges[idx.0].data
    }

    pub fn edge_data(&self, idx: EdgeIndex) -> &E {
        &self.edges[idx.0].data
    }

    pub fn edge(&self, idx: EdgeIndex) -> &Edge<E> {
        &self.edges[idx.0]
    }

    pub fn first_adjacent(&self, node: NodeIndex, dir: Direction) -> EdgeIndex {
        //! Accesses the index of the first edge adjacent to `node`.
        //! This is useful if you wish to modify the graph while walking
        //! the linked list of edges.

        self.nodes[node.0].first_edge[dir.repr]
    }

    pub fn next_adjacent(&self, edge: EdgeIndex, dir: Direction) -> EdgeIndex {
        //! Accesses the next edge in a given direction.
        //! This is useful if you wish to modify the graph while walking
        //! the linked list of edges.

        self.edges[edge.0].next_edge[dir.repr]
    }

    // # Iterating over nodes, edges

    pub fn each_node<'a, F>(&'a self, mut f: F) -> bool
        where F: FnMut(NodeIndex, &'a Node<N>) -> bool
    {
        //! Iterates over all edges defined in the graph.
        self.nodes.iter().enumerate().all(|(i, node)| f(NodeIndex(i), node))
    }

    pub fn each_edge<'a, F>(&'a self, mut f: F) -> bool
        where F: FnMut(EdgeIndex, &'a Edge<E>) -> bool
    {
        //! Iterates over all edges defined in the graph
        self.edges.iter().enumerate().all(|(i, edge)| f(EdgeIndex(i), edge))
    }

    pub fn outgoing_edges(&self, source: NodeIndex) -> AdjacentEdges<N, E> {
        self.adjacent_edges(source, OUTGOING)
    }

    pub fn incoming_edges(&self, source: NodeIndex) -> AdjacentEdges<N, E> {
        self.adjacent_edges(source, INCOMING)
    }

    pub fn adjacent_edges(&self, source: NodeIndex, direction: Direction) -> AdjacentEdges<N, E> {
        let first_edge = self.node(source).first_edge[direction.repr];
        AdjacentEdges {
            graph: self,
            direction: direction,
            next: first_edge,
        }
    }

    pub fn successor_nodes(&self, source: NodeIndex) -> AdjacentTargets<N, E> {
        self.outgoing_edges(source).targets()
    }

    pub fn predecessor_nodes(&self, target: NodeIndex) -> AdjacentSources<N, E> {
        self.incoming_edges(target).sources()
    }

    // # Fixed-point iteration
    //
    // A common use for graphs in our compiler is to perform
    // fixed-point iteration. In this case, each edge represents a
    // constraint, and the nodes themselves are associated with
    // variables or other bitsets. This method facilitates such a
    // computation.

    pub fn iterate_until_fixed_point<'a, F>(&'a self, mut op: F)
        where F: FnMut(usize, EdgeIndex, &'a Edge<E>) -> bool
    {
        let mut iteration = 0;
        let mut changed = true;
        while changed {
            changed = false;
            iteration += 1;
            for (i, edge) in self.edges.iter().enumerate() {
                changed |= op(iteration, EdgeIndex(i), edge);
            }
        }
    }

    pub fn depth_traverse<'a>(&'a self,
                              start: NodeIndex,
                              direction: Direction)
                              -> DepthFirstTraversal<'a, N, E> {
        DepthFirstTraversal::with_start_node(self, start, direction)
    }
}

// # Iterators

pub struct AdjacentEdges<'g, N, E>
    where N: 'g,
          E: 'g
{
    graph: &'g Graph<N, E>,
    direction: Direction,
    next: EdgeIndex,
}

impl<'g, N, E> AdjacentEdges<'g, N, E> {
    fn targets(self) -> AdjacentTargets<'g, N, E> {
        AdjacentTargets { edges: self }
    }

    fn sources(self) -> AdjacentSources<'g, N, E> {
        AdjacentSources { edges: self }
    }
}

impl<'g, N: Debug, E: Debug> Iterator for AdjacentEdges<'g, N, E> {
    type Item = (EdgeIndex, &'g Edge<E>);

    fn next(&mut self) -> Option<(EdgeIndex, &'g Edge<E>)> {
        let edge_index = self.next;
        if edge_index == INVALID_EDGE_INDEX {
            return None;
        }

        let edge = self.graph.edge(edge_index);
        self.next = edge.next_edge[self.direction.repr];
        Some((edge_index, edge))
    }
}

pub struct AdjacentTargets<'g, N, E>
    where N: 'g,
          E: 'g
{
    edges: AdjacentEdges<'g, N, E>,
}

impl<'g, N: Debug, E: Debug> Iterator for AdjacentTargets<'g, N, E> {
    type Item = NodeIndex;

    fn next(&mut self) -> Option<NodeIndex> {
        self.edges.next().map(|(_, edge)| edge.target)
    }
}

pub struct AdjacentSources<'g, N, E>
    where N: 'g,
          E: 'g
{
    edges: AdjacentEdges<'g, N, E>,
}

impl<'g, N: Debug, E: Debug> Iterator for AdjacentSources<'g, N, E> {
    type Item = NodeIndex;

    fn next(&mut self) -> Option<NodeIndex> {
        self.edges.next().map(|(_, edge)| edge.source)
    }
}

pub struct DepthFirstTraversal<'g, N, E>
    where N: 'g,
          E: 'g
{
    graph: &'g Graph<N, E>,
    stack: Vec<NodeIndex>,
    visited: BitVector,
    direction: Direction,
}

impl<'g, N: Debug, E: Debug> DepthFirstTraversal<'g, N, E> {
    pub fn new(graph: &'g Graph<N, E>, direction: Direction) -> Self {
        let visited = BitVector::new(graph.len_nodes());
        DepthFirstTraversal {
            graph: graph,
            stack: vec![],
            visited: visited,
            direction: direction,
        }
    }

    pub fn with_start_node(graph: &'g Graph<N, E>,
                           start_node: NodeIndex,
                           direction: Direction)
                           -> Self {
        let mut visited = BitVector::new(graph.len_nodes());
        visited.insert(start_node.node_id());
        DepthFirstTraversal {
            graph: graph,
            stack: vec![start_node],
            visited: visited,
            direction: direction,
        }
    }

    pub fn reset(&mut self, start_node: NodeIndex) {
        self.stack.truncate(0);
        self.stack.push(start_node);
        self.visited.clear();
        self.visited.insert(start_node.node_id());
    }

    fn visit(&mut self, node: NodeIndex) {
        if self.visited.insert(node.node_id()) {
            self.stack.push(node);
        }
    }
}

impl<'g, N: Debug, E: Debug> Iterator for DepthFirstTraversal<'g, N, E> {
    type Item = NodeIndex;

    fn next(&mut self) -> Option<NodeIndex> {
        let next = self.stack.pop();
        if let Some(idx) = next {
            for (_, edge) in self.graph.adjacent_edges(idx, self.direction) {
                let target = edge.source_or_target(self.direction);
                self.visit(target);
            }
        }
        next
    }
}

pub fn each_edge_index<F>(max_edge_index: EdgeIndex, mut f: F)
    where F: FnMut(EdgeIndex) -> bool
{
    let mut i = 0;
    let n = max_edge_index.0;
    while i < n {
        if !f(EdgeIndex(i)) {
            return;
        }
        i += 1;
    }
}

impl<E> Edge<E> {
    pub fn source(&self) -> NodeIndex {
        self.source
    }

    pub fn target(&self) -> NodeIndex {
        self.target
    }

    pub fn source_or_target(&self, direction: Direction) -> NodeIndex {
        if direction == OUTGOING {
            self.target
        } else {
            self.source
        }
    }
}
<commit_msg>Added general iterators for graph nodes and edges<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A graph module for use in dataflow, region resolution, and elsewhere.
//!
//! # Interface details
//!
//! You customize the graph by specifying a "node data" type `N` and an
//! "edge data" type `E`. You can then later gain access (mutable or
//! immutable) to these "user-data" bits. Currently, you can only add
//! nodes or edges to the graph. You cannot remove or modify them once
//! added. This could be changed if we have a need.
//!
//! # Implementation details
//!
//! The main tricky thing about this code is the way that edges are
//! stored. The edges are stored in a central array, but they are also
//! threaded onto two linked lists for each node, one for incoming edges
//! and one for outgoing edges. Note that every edge is a member of some
//! incoming list and some outgoing list.  Basically you can load the
//! first index of the linked list from the node data structures (the
//! field `first_edge`) and then, for each edge, load the next index from
//! the field `next_edge`). Each of those fields is an array that should
//! be indexed by the direction (see the type `Direction`).

use bitvec::BitVector;
use std::fmt::{Formatter, Error, Debug};
use std::usize;
use snapshot_vec::{SnapshotVec, SnapshotVecDelegate};

#[cfg(test)]
mod tests;

pub struct Graph<N, E> {
    nodes: SnapshotVec<Node<N>>,
    edges: SnapshotVec<Edge<E>>,
}

pub struct Node<N> {
    first_edge: [EdgeIndex; 2], // see module comment
    pub data: N,
}

pub struct Edge<E> {
    next_edge: [EdgeIndex; 2], // see module comment
    source: NodeIndex,
    target: NodeIndex,
    pub data: E,
}

impl<N> SnapshotVecDelegate for Node<N> {
    type Value = Node<N>;
    type Undo = ();

    fn reverse(_: &mut Vec<Node<N>>, _: ()) {}
}

impl<N> SnapshotVecDelegate for Edge<N> {
    type Value = Edge<N>;
    type Undo = ();

    fn reverse(_: &mut Vec<Edge<N>>, _: ()) {}
}

impl<E: Debug> Debug for Edge<E> {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f,
               "Edge {{ next_edge: [{:?}, {:?}], source: {:?}, target: {:?}, data: {:?} }}",
               self.next_edge[0],
               self.next_edge[1],
               self.source,
               self.target,
               self.data)
    }
}

#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub struct NodeIndex(pub usize);

#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub struct EdgeIndex(pub usize);

pub const INVALID_EDGE_INDEX: EdgeIndex = EdgeIndex(usize::MAX);

// Use a private field here to guarantee no more instances are created:
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Direction {
    repr: usize,
}

pub const OUTGOING: Direction = Direction { repr: 0 };

pub const INCOMING: Direction = Direction { repr: 1 };

impl NodeIndex {
    /// Returns unique id (unique with respect to the graph holding associated node).
    pub fn node_id(&self) -> usize {
        self.0
    }
}

impl EdgeIndex {
    /// Returns unique id (unique with respect to the graph holding associated edge).
    pub fn edge_id(&self) -> usize {
        self.0
    }
}

impl<N: Debug, E: Debug> Graph<N, E> {
    pub fn new() -> Graph<N, E> {
        Graph {
            nodes: SnapshotVec::new(),
            edges: SnapshotVec::new(),
        }
    }

    // # Simple accessors

    #[inline]
    pub fn all_nodes(&self) -> &[Node<N>] {
        &self.nodes
    }

    #[inline]
    pub fn len_nodes(&self) -> usize {
        self.nodes.len()
    }

    #[inline]
    pub fn all_edges(&self) -> &[Edge<E>] {
        &self.edges
    }

    #[inline]
    pub fn len_edges(&self) -> usize {
        self.edges.len()
    }

    // # Node construction

    pub fn next_node_index(&self) -> NodeIndex {
        NodeIndex(self.nodes.len())
    }

    pub fn add_node(&mut self, data: N) -> NodeIndex {
        let idx = self.next_node_index();
        self.nodes.push(Node {
            first_edge: [INVALID_EDGE_INDEX, INVALID_EDGE_INDEX],
            data: data,
        });
        idx
    }

    pub fn mut_node_data(&mut self, idx: NodeIndex) -> &mut N {
        &mut self.nodes[idx.0].data
    }

    pub fn node_data(&self, idx: NodeIndex) -> &N {
        &self.nodes[idx.0].data
    }

    pub fn node(&self, idx: NodeIndex) -> &Node<N> {
        &self.nodes[idx.0]
    }

    // # Edge construction and queries

    pub fn next_edge_index(&self) -> EdgeIndex {
        EdgeIndex(self.edges.len())
    }

    pub fn add_edge(&mut self, source: NodeIndex, target: NodeIndex, data: E) -> EdgeIndex {
        debug!("graph: add_edge({:?}, {:?}, {:?})", source, target, data);

        let idx = self.next_edge_index();

        // read current first of the list of edges from each node
        let source_first = self.nodes[source.0].first_edge[OUTGOING.repr];
        let target_first = self.nodes[target.0].first_edge[INCOMING.repr];

        // create the new edge, with the previous firsts from each node
        // as the next pointers
        self.edges.push(Edge {
            next_edge: [source_first, target_first],
            source: source,
            target: target,
            data: data,
        });

        // adjust the firsts for each node target be the next object.
        self.nodes[source.0].first_edge[OUTGOING.repr] = idx;
        self.nodes[target.0].first_edge[INCOMING.repr] = idx;

        return idx;
    }

    pub fn mut_edge_data(&mut self, idx: EdgeIndex) -> &mut E {
        &mut self.edges[idx.0].data
    }

    pub fn edge_data(&self, idx: EdgeIndex) -> &E {
        &self.edges[idx.0].data
    }

    pub fn edge(&self, idx: EdgeIndex) -> &Edge<E> {
        &self.edges[idx.0]
    }

    pub fn first_adjacent(&self, node: NodeIndex, dir: Direction) -> EdgeIndex {
        //! Accesses the index of the first edge adjacent to `node`.
        //! This is useful if you wish to modify the graph while walking
        //! the linked list of edges.

        self.nodes[node.0].first_edge[dir.repr]
    }

    pub fn next_adjacent(&self, edge: EdgeIndex, dir: Direction) -> EdgeIndex {
        //! Accesses the next edge in a given direction.
        //! This is useful if you wish to modify the graph while walking
        //! the linked list of edges.

        self.edges[edge.0].next_edge[dir.repr]
    }

    // # Iterating over nodes, edges

    pub fn all_nodes_enumerated(&self) -> Nodes<N> {
        Nodes {
            iter: self.nodes.iter().enumerate()
        }
    }

    pub fn all_edges_enumerated(&self) -> Edges<E> {
        Edges {
            iter: self.edges.iter().enumerate()
        }
    }

    pub fn each_node<'a, F>(&'a self, mut f: F) -> bool
        where F: FnMut(NodeIndex, &'a Node<N>) -> bool
    {
        //! Iterates over all edges defined in the graph.
        self.all_nodes_enumerated().all(|(node_idx, node)| f(node_idx, node))
    }

    pub fn each_edge<'a, F>(&'a self, mut f: F) -> bool
        where F: FnMut(EdgeIndex, &'a Edge<E>) -> bool
    {
        //! Iterates over all edges defined in the graph
        self.all_edges_enumerated().all(|(edge_idx, edge)| f(edge_idx, edge))
    }

    pub fn outgoing_edges(&self, source: NodeIndex) -> AdjacentEdges<N, E> {
        self.adjacent_edges(source, OUTGOING)
    }

    pub fn incoming_edges(&self, source: NodeIndex) -> AdjacentEdges<N, E> {
        self.adjacent_edges(source, INCOMING)
    }

    pub fn adjacent_edges(&self, source: NodeIndex, direction: Direction) -> AdjacentEdges<N, E> {
        let first_edge = self.node(source).first_edge[direction.repr];
        AdjacentEdges {
            graph: self,
            direction: direction,
            next: first_edge,
        }
    }

    pub fn successor_nodes(&self, source: NodeIndex) -> AdjacentTargets<N, E> {
        self.outgoing_edges(source).targets()
    }

    pub fn predecessor_nodes(&self, target: NodeIndex) -> AdjacentSources<N, E> {
        self.incoming_edges(target).sources()
    }

    // # Fixed-point iteration
    //
    // A common use for graphs in our compiler is to perform
    // fixed-point iteration. In this case, each edge represents a
    // constraint, and the nodes themselves are associated with
    // variables or other bitsets. This method facilitates such a
    // computation.

    pub fn iterate_until_fixed_point<'a, F>(&'a self, mut op: F)
        where F: FnMut(usize, EdgeIndex, &'a Edge<E>) -> bool
    {
        let mut iteration = 0;
        let mut changed = true;
        while changed {
            changed = false;
            iteration += 1;
            for (edge_index, edge) in self.all_edges_enumerated() {
                changed |= op(iteration, edge_index, edge);
            }
        }
    }

    pub fn depth_traverse<'a>(&'a self,
                              start: NodeIndex,
                              direction: Direction)
                              -> DepthFirstTraversal<'a, N, E> {
        DepthFirstTraversal::with_start_node(self, start, direction)
    }
}

// # Iterators

pub struct Nodes<'g, N>
    where N: 'g,
{
    iter: ::std::iter::Enumerate<::std::slice::Iter<'g, Node<N>>>
}

impl<'g, N: Debug> Iterator for Nodes<'g, N> {
    type Item = (NodeIndex, &'g Node<N>);

    fn next(&mut self) -> Option<(NodeIndex, &'g Node<N>)> {
        self.iter.next().map(|(idx, n)| (NodeIndex(idx), n))
    }
}

pub struct Edges<'g, E>
    where E: 'g,
{
    iter: ::std::iter::Enumerate<::std::slice::Iter<'g, Edge<E>>>
}

impl<'g, E: Debug> Iterator for Edges<'g, E> {
    type Item = (EdgeIndex, &'g Edge<E>);

    fn next(&mut self) -> Option<(EdgeIndex, &'g Edge<E>)> {
        self.iter.next().map(|(idx, e)| (EdgeIndex(idx), e))
    }
}

pub struct AdjacentEdges<'g, N, E>
    where N: 'g,
          E: 'g
{
    graph: &'g Graph<N, E>,
    direction: Direction,
    next: EdgeIndex,
}

impl<'g, N, E> AdjacentEdges<'g, N, E> {
    fn targets(self) -> AdjacentTargets<'g, N, E> {
        AdjacentTargets { edges: self }
    }

    fn sources(self) -> AdjacentSources<'g, N, E> {
        AdjacentSources { edges: self }
    }
}

impl<'g, N: Debug, E: Debug> Iterator for AdjacentEdges<'g, N, E> {
    type Item = (EdgeIndex, &'g Edge<E>);

    fn next(&mut self) -> Option<(EdgeIndex, &'g Edge<E>)> {
        let edge_index = self.next;
        if edge_index == INVALID_EDGE_INDEX {
            return None;
        }

        let edge = self.graph.edge(edge_index);
        self.next = edge.next_edge[self.direction.repr];
        Some((edge_index, edge))
    }
}

pub struct AdjacentTargets<'g, N, E>
    where N: 'g,
          E: 'g
{
    edges: AdjacentEdges<'g, N, E>,
}

impl<'g, N: Debug, E: Debug> Iterator for AdjacentTargets<'g, N, E> {
    type Item = NodeIndex;

    fn next(&mut self) -> Option<NodeIndex> {
        self.edges.next().map(|(_, edge)| edge.target)
    }
}

pub struct AdjacentSources<'g, N, E>
    where N: 'g,
          E: 'g
{
    edges: AdjacentEdges<'g, N, E>,
}

impl<'g, N: Debug, E: Debug> Iterator for AdjacentSources<'g, N, E> {
    type Item = NodeIndex;

    fn next(&mut self) -> Option<NodeIndex> {
        self.edges.next().map(|(_, edge)| edge.source)
    }
}

pub struct DepthFirstTraversal<'g, N, E>
    where N: 'g,
          E: 'g
{
    graph: &'g Graph<N, E>,
    stack: Vec<NodeIndex>,
    visited: BitVector,
    direction: Direction,
}

impl<'g, N: Debug, E: Debug> DepthFirstTraversal<'g, N, E> {
    pub fn new(graph: &'g Graph<N, E>, direction: Direction) -> Self {
        let visited = BitVector::new(graph.len_nodes());
        DepthFirstTraversal {
            graph: graph,
            stack: vec![],
            visited: visited,
            direction: direction,
        }
    }

    pub fn with_start_node(graph: &'g Graph<N, E>,
                           start_node: NodeIndex,
                           direction: Direction)
                           -> Self {
        let mut visited = BitVector::new(graph.len_nodes());
        visited.insert(start_node.node_id());
        DepthFirstTraversal {
            graph: graph,
            stack: vec![start_node],
            visited: visited,
            direction: direction,
        }
    }

    pub fn reset(&mut self, start_node: NodeIndex) {
        self.stack.truncate(0);
        self.stack.push(start_node);
        self.visited.clear();
        self.visited.insert(start_node.node_id());
    }

    fn visit(&mut self, node: NodeIndex) {
        if self.visited.insert(node.node_id()) {
            self.stack.push(node);
        }
    }
}

impl<'g, N: Debug, E: Debug> Iterator for DepthFirstTraversal<'g, N, E> {
    type Item = NodeIndex;

    fn next(&mut self) -> Option<NodeIndex> {
        let next = self.stack.pop();
        if let Some(idx) = next {
            for (_, edge) in self.graph.adjacent_edges(idx, self.direction) {
                let target = edge.source_or_target(self.direction);
                self.visit(target);
            }
        }
        next
    }
}

pub fn each_edge_index<F>(max_edge_index: EdgeIndex, mut f: F)
    where F: FnMut(EdgeIndex) -> bool
{
    let mut i = 0;
    let n = max_edge_index.0;
    while i < n {
        if !f(EdgeIndex(i)) {
            return;
        }
        i += 1;
    }
}

impl<E> Edge<E> {
    pub fn source(&self) -> NodeIndex {
        self.source
    }

    pub fn target(&self) -> NodeIndex {
        self.target
    }

    pub fn source_or_target(&self, direction: Direction) -> NodeIndex {
        if direction == OUTGOING {
            self.target
        } else {
            self.source
        }
    }
}
<|endoftext|>