<commit_before>//
//   Copyright 2016 Andrew Hunter
//
//   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.
//

//!
//! A symbol reader reads one symbol at a time from a source
//!

use std::slice::Iter;
use std::io::Read;
use std::io::Bytes;
use std::str::Chars;
use std::marker::PhantomData;

///
/// A symbol reader reads one symbol at a time from a source
///
pub trait SymbolReader<Symbol> {
    ///
    /// Reads the next symbol from this reader
    ///
    fn next_symbol(&mut self) -> Option<Symbol>;
}

///
/// Trait that can be implemented by things that can construct a symbol reader
///
pub trait SymbolSource<'a, Symbol> {
    /// The type of symbol reader that will be generated by this call
    type SymbolReader: SymbolReader<Symbol>+'a;

    /// Returns a new object that can read the symbols from this one
    fn read_symbols(self) -> Self::SymbolReader;
}

impl<'a, Symbol: Clone+'a> SymbolSource<'a, Symbol> for &'a Vec<Symbol> {
    type SymbolReader = Iter<'a, Symbol>;

    fn read_symbols(self) -> Self::SymbolReader {
        self.iter()
    }
}

impl<'a, Symbol: Clone+'a> SymbolReader<Symbol> for Iter<'a, Symbol> {
    fn next_symbol(&mut self) -> Option<Symbol> {
        if let Some(sym) = self.next() {
            Some(sym.clone())
        } else {
            None
        }
    }
}

// Can read from streams

//
// TODO: implementing SymbolSource for Read would be nice
// It's just a matter of calling bytes() on the appropriate type, but Rust's type system is simultaneously too clever and not clever enough
// to allow that in any sensible way. You can't do it an an arbitrary Read because the Bytes object is not sized without knowing its real
// type; I couldn't figure out a trick using the Self type to get around that, though those do work sometimes.
// `impl<X: Read> SymbolReader for X` sounds like a nice idea but Rust thinks X can be anything and won't allow any other implementations
// of the interface, which makes that useless too.
// Screwing around with lifetimes and references like below seems like it should work, but Rust doesn't seem to see the implementations on
// actual streams.
//

/*
impl<'a> SymbolSource<'a, u8> for &'a mut Read {
    type SymbolReader = ByteSymbolReader<Self>;

    fn read_symbols(self) -> Self::SymbolReader {
        ByteSymbolReader::new(self.bytes())
    }
}

impl<'a> SymbolSource<'a, u8> for &'a mut BufRead {
    type SymbolReader = ByteSymbolReader<Self>;

    fn read_symbols(self) -> Self::SymbolReader {
        ByteSymbolReader::new(self.bytes())
    }
}
*/

///
/// The ByteSymbolReader turns a `std::io::Bytes` object into a symbol reader
///
pub struct ByteSymbolReader<Reader: Read> {
    bytes: Bytes<Reader>
}

impl<Reader: Read> ByteSymbolReader<Reader> {
    pub fn new(bytes: Bytes<Reader>) -> ByteSymbolReader<Reader> {
        ByteSymbolReader { bytes: bytes }
    }

    pub fn from(reader: Reader) -> ByteSymbolReader<Reader> {
        Self::new(reader.bytes())
    }
}

impl<Reader: Read> SymbolReader<u8> for ByteSymbolReader<Reader> {
    fn next_symbol(&mut self) -> Option<u8> {
        if let Some(Ok(sym)) = self.bytes.next() {
            Some(sym.clone())
        } else {
            None
        }
    }
}

//
// Can read from strings
//
impl<'a> SymbolSource<'a, char> for &'a str {
    type SymbolReader = Chars<'a>;

    fn read_symbols(self) -> Self::SymbolReader {
        self.chars()
    }
}

impl<'a> SymbolReader<char> for Chars<'a> {
    fn next_symbol(&mut self) -> Option<char> {
        self.next()
    }
}

//
// Boxed symbol readers act like normal symbol readers
//
impl<'a, Symbol> SymbolReader<Symbol> for Box<SymbolReader<Symbol>+'a> {
    fn next_symbol(&mut self) -> Option<Symbol> {
        (**self).next_symbol()
    }
}

///
/// Converts symbol streams to vectors
///
pub trait ReaderToVector<Symbol> {
    /// Reads every symbol in this object and returns a vector
    fn to_vec(&mut self) -> Vec<Symbol>;
}

impl<Symbol, Reader: SymbolReader<Symbol>> ReaderToVector<Symbol> for Reader {
    #[inline]
    fn to_vec(&mut self) -> Vec<Symbol> {
        let mut result = vec![];

        while let Some(symbol) = self.next_symbol() {
            result.push(symbol);
        }

        result
    }
}

///
/// A symbol stream that performs mapping of symbols from a source stream
///
pub struct MappedStream<InputSymbol, MapFunction, Reader>
where Reader: SymbolReader<InputSymbol> {
    /// The source stream
    source_stream: Reader,

    /// A function used to map a symbol from the source stream to a symbol in the output stream
    mapping_function: MapFunction,

    /// Can't see how to eliminate the input symbol reference due to rust's type system. InputSymbol is used by source_stream, but rust can't see that
    #[allow(dead_code)]
    phantom: PhantomData<InputSymbol>
}

///
/// Provides a way to map symbol streams to streams of other types
///
pub trait MapSymbolReader<Symbol> : SymbolReader<Symbol>+Sized {
    /// Maps symbols in this stream to symbols in a new stream
    fn map_symbols<OutputSymbol, MapFunction>(self, mapping_function: MapFunction) -> MappedStream<Symbol, MapFunction, Self>
    where MapFunction: FnMut(Symbol) -> OutputSymbol;
}

impl<Symbol, Reader: SymbolReader<Symbol>> MapSymbolReader<Symbol> for Reader {
    fn map_symbols<OutputSymbol, MapFunction>(self, mapping_function: MapFunction) -> MappedStream<Symbol, MapFunction, Self>
    where MapFunction: FnMut(Symbol) -> OutputSymbol {
        MappedStream {
            source_stream:    self,
            mapping_function: mapping_function,
            phantom:          PhantomData
        }
    }
}

impl<InputSymbol, OutputSymbol, MapFunction, Reader: SymbolReader<InputSymbol>> SymbolReader<OutputSymbol> for MappedStream<InputSymbol, MapFunction, Reader>
where MapFunction: FnMut(InputSymbol) -> OutputSymbol {
    // TODO: would like to eliminate InputSymbol as phantom data from the structure
    // This means removing the constraint on Reader. That doesn't work because rust then thinks InputSymbol is unconstrained here,
    // even though it's constrained by the function type, the reader type *and* the structure type

    fn next_symbol(&mut self) -> Option<OutputSymbol> {
        if let Some(input_symbol) = self.source_stream.next_symbol() {
            Some((self.mapping_function)(input_symbol))
        } else {
            None
        }
    }
}

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

    #[test]
    fn can_read_from_vec() {
        let source      = vec![1, 2, 3];
        let mut reader  = source.read_symbols();

        assert!(reader.next_symbol() == Some(1));
        assert!(reader.next_symbol() == Some(2));
        assert!(reader.next_symbol() == Some(3));
        assert!(reader.next_symbol() == None);
    }

    #[test]
    fn can_convert_to_vec() {
        let source      = vec![1, 2, 3];
        let mut reader  = source.read_symbols();
        let result      = reader.to_vec();

        assert!(result == vec![1, 2, 3]);
    }

    #[test]
    fn can_map_stream() {
        let source      = vec![1, 2, 3];
        let mut reader  = source.read_symbols();
        let result      = reader.map_symbols(|sym| sym+1).to_vec();

        assert!(result == vec![2, 3, 4]);
    }

    #[test]
    fn can_read_from_bytes_reader() {
        let array: [u8; 3] = [1, 2, 3];
        let slice = &array[..];
        let mut reader = ByteSymbolReader::from(slice);

        assert!(reader.next_symbol() == Some(1));
        assert!(reader.next_symbol() == Some(2));
        assert!(reader.next_symbol() == Some(3));
        assert!(reader.next_symbol() == None);
    }

    #[test]
    fn can_read_from_string_reader() {
        let mut reader = "abc".read_symbols();

        assert!(reader.next_symbol() == Some('a'));
        assert!(reader.next_symbol() == Some('b'));
        assert!(reader.next_symbol() == Some('c'));
        assert!(reader.next_symbol() == None);
    }
}
<commit_msg>Update comments<commit_after>//
//   Copyright 2016 Andrew Hunter
//
//   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.
//

//!
//! A symbol reader reads one symbol at a time from a source
//!

use std::slice::Iter;
use std::io::Read;
use std::io::Bytes;
use std::str::Chars;
use std::marker::PhantomData;

///
/// A symbol reader reads one symbol at a time from a source
///
pub trait SymbolReader<Symbol> {
    ///
    /// Reads the next symbol from this reader
    ///
    fn next_symbol(&mut self) -> Option<Symbol>;
}

///
/// Trait that can be implemented by things that can construct a symbol reader
///
pub trait SymbolSource<'a, Symbol> {
    /// The type of symbol reader that will be generated by this call
    type SymbolReader: SymbolReader<Symbol>+'a;

    /// Returns a new object that can read the symbols from this one
    fn read_symbols(self) -> Self::SymbolReader;
}

impl<'a, Symbol: Clone+'a> SymbolSource<'a, Symbol> for &'a Vec<Symbol> {
    type SymbolReader = Iter<'a, Symbol>;

    fn read_symbols(self) -> Self::SymbolReader {
        self.iter()
    }
}

impl<'a, Symbol: Clone+'a> SymbolReader<Symbol> for Iter<'a, Symbol> {
    fn next_symbol(&mut self) -> Option<Symbol> {
        if let Some(sym) = self.next() {
            Some(sym.clone())
        } else {
            None
        }
    }
}

// Can read from streams

//
// TODO: implementing SymbolSource for Read would be nice
// It's just a matter of calling bytes() on the appropriate type, but Rust's type system is simultaneously too clever and not clever enough
// to allow that in any sensible way. You can't do it an an arbitrary Read because the Bytes object is not sized without knowing its real
// type; I couldn't figure out a trick using the Self type to get around that, though those do work sometimes.
// `impl<X: Read> SymbolReader for X` sounds like a nice idea but Rust thinks X can be anything and won't allow any other implementations
// of the interface, which makes that useless too.
// Screwing around with lifetimes and references like below seems like it should work, but Rust doesn't seem to see the implementations on
// actual streams.
//

/*
impl<'a> SymbolSource<'a, u8> for &'a mut Read {
    type SymbolReader = ByteSymbolReader<Self>;

    fn read_symbols(self) -> Self::SymbolReader {
        ByteSymbolReader::new(self.bytes())
    }
}

impl<'a> SymbolSource<'a, u8> for &'a mut BufRead {
    type SymbolReader = ByteSymbolReader<Self>;

    fn read_symbols(self) -> Self::SymbolReader {
        ByteSymbolReader::new(self.bytes())
    }
}
*/

///
/// The ByteSymbolReader turns a `std::io::Bytes` object into a symbol reader
///
pub struct ByteSymbolReader<Reader: Read> {
    bytes: Bytes<Reader>
}

impl<Reader: Read> ByteSymbolReader<Reader> {
    pub fn new(bytes: Bytes<Reader>) -> ByteSymbolReader<Reader> {
        ByteSymbolReader { bytes: bytes }
    }

    pub fn from(reader: Reader) -> ByteSymbolReader<Reader> {
        Self::new(reader.bytes())
    }
}

impl<Reader: Read> SymbolReader<u8> for ByteSymbolReader<Reader> {
    fn next_symbol(&mut self) -> Option<u8> {
        if let Some(Ok(sym)) = self.bytes.next() {
            Some(sym.clone())
        } else {
            None
        }
    }
}

//
// Can read from strings
//
impl<'a> SymbolSource<'a, char> for &'a str {
    type SymbolReader = Chars<'a>;

    fn read_symbols(self) -> Self::SymbolReader {
        self.chars()
    }
}

impl<'a> SymbolReader<char> for Chars<'a> {
    fn next_symbol(&mut self) -> Option<char> {
        self.next()
    }
}

//
// Boxed symbol readers act like normal symbol readers
//
// Note the lifetime specifier here (boxes are static by default which can cause a super confusing error message)
//
impl<'a, Symbol> SymbolReader<Symbol> for Box<SymbolReader<Symbol>+'a> {
    fn next_symbol(&mut self) -> Option<Symbol> {
        (**self).next_symbol()
    }
}

///
/// Converts symbol streams to vectors
///
pub trait ReaderToVector<Symbol> {
    /// Reads every symbol in this object and returns a vector
    fn to_vec(&mut self) -> Vec<Symbol>;
}

impl<Symbol, Reader: SymbolReader<Symbol>> ReaderToVector<Symbol> for Reader {
    #[inline]
    fn to_vec(&mut self) -> Vec<Symbol> {
        let mut result = vec![];

        while let Some(symbol) = self.next_symbol() {
            result.push(symbol);
        }

        result
    }
}

///
/// A symbol stream that performs mapping of symbols from a source stream
///
pub struct MappedStream<InputSymbol, MapFunction, Reader>
where Reader: SymbolReader<InputSymbol> {
    /// The source stream
    source_stream: Reader,

    /// A function used to map a symbol from the source stream to a symbol in the output stream
    mapping_function: MapFunction,

    /// Can't see how to eliminate the input symbol reference due to rust's type system. InputSymbol is used by source_stream, but rust can't see that
    #[allow(dead_code)]
    phantom: PhantomData<InputSymbol>
}

///
/// Provides a way to map symbol streams to streams of other types
///
pub trait MapSymbolReader<Symbol> : SymbolReader<Symbol>+Sized {
    /// Maps symbols in this stream to symbols in a new stream
    fn map_symbols<OutputSymbol, MapFunction>(self, mapping_function: MapFunction) -> MappedStream<Symbol, MapFunction, Self>
    where MapFunction: FnMut(Symbol) -> OutputSymbol;
}

impl<Symbol, Reader: SymbolReader<Symbol>> MapSymbolReader<Symbol> for Reader {
    fn map_symbols<OutputSymbol, MapFunction>(self, mapping_function: MapFunction) -> MappedStream<Symbol, MapFunction, Self>
    where MapFunction: FnMut(Symbol) -> OutputSymbol {
        MappedStream {
            source_stream:    self,
            mapping_function: mapping_function,
            phantom:          PhantomData
        }
    }
}

impl<InputSymbol, OutputSymbol, MapFunction, Reader: SymbolReader<InputSymbol>> SymbolReader<OutputSymbol> for MappedStream<InputSymbol, MapFunction, Reader>
where MapFunction: FnMut(InputSymbol) -> OutputSymbol {
    // TODO: would like to eliminate InputSymbol as phantom data from the structure
    // This means removing the constraint on Reader. That doesn't work because rust then thinks InputSymbol is unconstrained here,
    // even though it's constrained by the function type, the reader type *and* the structure type

    fn next_symbol(&mut self) -> Option<OutputSymbol> {
        if let Some(input_symbol) = self.source_stream.next_symbol() {
            Some((self.mapping_function)(input_symbol))
        } else {
            None
        }
    }
}

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

    #[test]
    fn can_read_from_vec() {
        let source      = vec![1, 2, 3];
        let mut reader  = source.read_symbols();

        assert!(reader.next_symbol() == Some(1));
        assert!(reader.next_symbol() == Some(2));
        assert!(reader.next_symbol() == Some(3));
        assert!(reader.next_symbol() == None);
    }

    #[test]
    fn can_convert_to_vec() {
        let source      = vec![1, 2, 3];
        let mut reader  = source.read_symbols();
        let result      = reader.to_vec();

        assert!(result == vec![1, 2, 3]);
    }

    #[test]
    fn can_map_stream() {
        let source      = vec![1, 2, 3];
        let mut reader  = source.read_symbols();
        let result      = reader.map_symbols(|sym| sym+1).to_vec();

        assert!(result == vec![2, 3, 4]);
    }

    #[test]
    fn can_read_from_bytes_reader() {
        let array: [u8; 3] = [1, 2, 3];
        let slice = &array[..];
        let mut reader = ByteSymbolReader::from(slice);

        assert!(reader.next_symbol() == Some(1));
        assert!(reader.next_symbol() == Some(2));
        assert!(reader.next_symbol() == Some(3));
        assert!(reader.next_symbol() == None);
    }

    #[test]
    fn can_read_from_string_reader() {
        let mut reader = "abc".read_symbols();

        assert!(reader.next_symbol() == Some('a'));
        assert!(reader.next_symbol() == Some('b'));
        assert!(reader.next_symbol() == Some('c'));
        assert!(reader.next_symbol() == None);
    }
}
<|endoftext|>


<commit_before>extern crate hyper;

use self::hyper::client::Client;

use std::thread;
use std::time::Duration;

use super::{Image,process_downloads,req_and_parse};

use std::sync::mpsc::Receiver;

pub fn main(rc: &Receiver<()>) {
    let client = Client::new();
    let mut url_string = "https://konachan.com/post.json?limit=100".to_string();
    let mut page = 1;

    loop {
        let res = match req_and_parse(&client, &url_string) {
            Ok(x) => x,
            Err(_) => {
                thread::sleep(Duration::new(3,0));
                continue
            }
        };

        let images = res.as_array().unwrap();
        if images.is_empty() { break }

        let images = images.iter().fold(Vec::new(), |mut acc, x| {
            let image = x.as_object().unwrap();
            let tags = image["tags"].as_string().unwrap().split_whitespace().map(String::from).collect::<Vec<_>>();
            let rating = image["rating"].as_string().unwrap().chars().nth(0).unwrap();

            let url = image["file_url"].as_string().unwrap().to_string();

            let ext = url.clone();
            let ext = ext.split('.').collect::<Vec<_>>();
            let ext = ext.last().unwrap();

            let id = image["id"].as_i64().unwrap();
            let score = image["score"].as_i64().unwrap();

            let name = format!("konachan_{}.{}", id, ext);

            acc.push(Image{
                name: name.to_string(),
                got_from: "konachan".to_string(),
                url: url,
                tags: tags,
                rating: rating,
                post_url: format!("http://konachan.com/post/show/{}", id),
                score: score as i32
            });
            acc
        });

        if process_downloads(&client, &images, rc).is_err() { break }

        page += 1;

        url_string = format!("https://konachan.com/post.json?page={}&limit=100", page);
    }
}
<commit_msg>100 -> 500 konachan<commit_after>extern crate hyper;

use self::hyper::client::Client;

use std::thread;
use std::time::Duration;

use super::{Image,process_downloads,req_and_parse};

use std::sync::mpsc::Receiver;

pub fn main(rc: &Receiver<()>) {
    let client = Client::new();
    let mut url_string = "https://konachan.com/post.json?limit=500".to_string(); // Konachan вроде как вообще не ограничивает
    let mut page = 1;

    loop {
        let res = match req_and_parse(&client, &url_string) {
            Ok(x) => x,
            Err(_) => {
                thread::sleep(Duration::new(3,0));
                continue
            }
        };

        let images = res.as_array().unwrap();
        if images.is_empty() { break }

        let images = images.iter().fold(Vec::new(), |mut acc, x| {
            let image = x.as_object().unwrap();
            let tags = image["tags"].as_string().unwrap().split_whitespace().map(String::from).collect::<Vec<_>>();
            let rating = image["rating"].as_string().unwrap().chars().nth(0).unwrap();

            let url = image["file_url"].as_string().unwrap().to_string();

            let ext = url.clone();
            let ext = ext.split('.').collect::<Vec<_>>();
            let ext = ext.last().unwrap();

            let id = image["id"].as_i64().unwrap();
            let score = image["score"].as_i64().unwrap();

            let name = format!("konachan_{}.{}", id, ext);

            acc.push(Image{
                name: name.to_string(),
                got_from: "konachan".to_string(),
                url: url,
                tags: tags,
                rating: rating,
                post_url: format!("http://konachan.com/post/show/{}", id),
                score: score as i32
            });
            acc
        });

        if process_downloads(&client, &images, rc).is_err() { break }

        page += 1;

        url_string = format!("https://konachan.com/post.json?page={}&limit=100", page);
    }
}
<|endoftext|>


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

//! This module provides linkage between libgraphviz traits and
//! `rustc::middle::typeck::infer::region_inference`, generating a
//! rendering of the graph represented by the list of `Constraint`
//! instances (which make up the edges of the graph), as well as the
//! origin for each constraint (which are attached to the labels on
//! each edge).

/// For clarity, rename the graphviz crate locally to dot.
use graphviz as dot;

use ty::{self, TyCtxt};
use middle::region::CodeExtent;
use super::Constraint;
use infer::SubregionOrigin;
use infer::region_inference::RegionVarBindings;
use util::nodemap::{FxHashMap, FxHashSet};

use std::borrow::Cow;
use std::collections::hash_map::Entry::Vacant;
use std::env;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::sync::atomic::{AtomicBool, Ordering};
use syntax::ast;

fn print_help_message() {
    println!("\
-Z print-region-graph by default prints a region constraint graph for every \n\
function body, to the path `/tmp/constraints.nodeXXX.dot`, where the XXX is \n\
replaced with the node id of the function under analysis.                   \n\
                                                                            \n\
To select one particular function body, set `RUST_REGION_GRAPH_NODE=XXX`,   \n\
where XXX is the node id desired.                                           \n\
                                                                            \n\
To generate output to some path other than the default                      \n\
`/tmp/constraints.nodeXXX.dot`, set `RUST_REGION_GRAPH=/path/desired.dot`;  \n\
occurrences of the character `%` in the requested path will be replaced with\n\
the node id of the function under analysis.                                 \n\
                                                                            \n\
(Since you requested help via RUST_REGION_GRAPH=help, no region constraint  \n\
graphs will be printed.                                                     \n\
");
}

pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
    region_vars: &RegionVarBindings<'a, 'gcx, 'tcx>,
    subject_node: ast::NodeId)
{
    let tcx = region_vars.tcx;

    if !region_vars.tcx.sess.opts.debugging_opts.print_region_graph {
        return;
    }

    let requested_node = env::var("RUST_REGION_GRAPH_NODE")
        .ok().and_then(|s| s.parse().map(ast::NodeId::new).ok());

    if requested_node.is_some() && requested_node != Some(subject_node) {
        return;
    }

    let requested_output = env::var("RUST_REGION_GRAPH");
    debug!("requested_output: {:?} requested_node: {:?}",
           requested_output,
           requested_node);

    let output_path = {
        let output_template = match requested_output {
            Ok(ref s) if s == "help" => {
                static PRINTED_YET: AtomicBool = AtomicBool::new(false);
                if !PRINTED_YET.load(Ordering::SeqCst) {
                    print_help_message();
                    PRINTED_YET.store(true, Ordering::SeqCst);
                }
                return;
            }

            Ok(other_path) => other_path,
            Err(_) => "/tmp/constraints.node%.dot".to_string(),
        };

        if output_template.is_empty() {
            bug!("empty string provided as RUST_REGION_GRAPH");
        }

        if output_template.contains('%') {
            let mut new_str = String::new();
            for c in output_template.chars() {
                if c == '%' {
                    new_str.push_str(&subject_node.to_string());
                } else {
                    new_str.push(c);
                }
            }
            new_str
        } else {
            output_template
        }
    };

    let constraints = &*region_vars.constraints.borrow();
    match dump_region_constraints_to(tcx, constraints, &output_path) {
        Ok(()) => {}
        Err(e) => {
            let msg = format!("io error dumping region constraints: {}", e);
            region_vars.tcx.sess.err(&msg)
        }
    }
}

struct ConstraintGraph<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
    tcx: TyCtxt<'a, 'gcx, 'tcx>,
    graph_name: String,
    map: &'a FxHashMap<Constraint<'tcx>, SubregionOrigin<'tcx>>,
    node_ids: FxHashMap<Node, usize>,
}

#[derive(Clone, Hash, PartialEq, Eq, Debug, Copy)]
enum Node {
    RegionVid(ty::RegionVid),
    Region(ty::Region),
}

// type Edge = Constraint;
#[derive(Clone, PartialEq, Eq, Debug, Copy)]
enum Edge<'tcx> {
    Constraint(Constraint<'tcx>),
    EnclScope(CodeExtent, CodeExtent),
}

impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> {
    fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
           name: String,
           map: &'a ConstraintMap<'tcx>)
           -> ConstraintGraph<'a, 'gcx, 'tcx> {
        let mut i = 0;
        let mut node_ids = FxHashMap();
        {
            let mut add_node = |node| {
                if let Vacant(e) = node_ids.entry(node) {
                    e.insert(i);
                    i += 1;
                }
            };

            for (n1, n2) in map.keys().map(|c| constraint_to_nodes(c)) {
                add_node(n1);
                add_node(n2);
            }

            tcx.region_maps.each_encl_scope(|sub, sup| {
                add_node(Node::Region(ty::ReScope(*sub)));
                add_node(Node::Region(ty::ReScope(*sup)));
            });
        }

        ConstraintGraph {
            tcx: tcx,
            graph_name: name,
            map: map,
            node_ids: node_ids,
        }
    }
}

impl<'a, 'gcx, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
    type Node = Node;
    type Edge = Edge<'tcx>;
    fn graph_id(&self) -> dot::Id {
        dot::Id::new(&*self.graph_name).unwrap()
    }
    fn node_id(&self, n: &Node) -> dot::Id {
        let node_id = match self.node_ids.get(n) {
            Some(node_id) => node_id,
            None => bug!("no node_id found for node: {:?}", n),
        };
        let name = || format!("node_{}", node_id);
        match dot::Id::new(name()) {
            Ok(id) => id,
            Err(_) => {
                bug!("failed to create graphviz node identified by {}", name());
            }
        }
    }
    fn node_label(&self, n: &Node) -> dot::LabelText {
        match *n {
            Node::RegionVid(n_vid) => dot::LabelText::label(format!("{:?}", n_vid)),
            Node::Region(n_rgn) => dot::LabelText::label(format!("{:?}", n_rgn)),
        }
    }
    fn edge_label(&self, e: &Edge) -> dot::LabelText {
        match *e {
            Edge::Constraint(ref c) =>
                dot::LabelText::label(format!("{:?}", self.map.get(c).unwrap())),
            Edge::EnclScope(..) => dot::LabelText::label(format!("(enclosed)")),
        }
    }
}

fn constraint_to_nodes(c: &Constraint) -> (Node, Node) {
    match *c {
        Constraint::ConstrainVarSubVar(rv_1, rv_2) =>
            (Node::RegionVid(rv_1), Node::RegionVid(rv_2)),
        Constraint::ConstrainRegSubVar(r_1, rv_2) =>
            (Node::Region(*r_1), Node::RegionVid(rv_2)),
        Constraint::ConstrainVarSubReg(rv_1, r_2) =>
            (Node::RegionVid(rv_1), Node::Region(*r_2)),
        Constraint::ConstrainRegSubReg(r_1, r_2) =>
            (Node::Region(*r_1), Node::Region(*r_2)),
    }
}

fn edge_to_nodes(e: &Edge) -> (Node, Node) {
    match *e {
        Edge::Constraint(ref c) => constraint_to_nodes(c),
        Edge::EnclScope(sub, sup) => {
            (Node::Region(ty::ReScope(sub)),
             Node::Region(ty::ReScope(sup)))
        }
    }
}

impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
    type Node = Node;
    type Edge = Edge<'tcx>;
    fn nodes(&self) -> dot::Nodes<Node> {
        let mut set = FxHashSet();
        for node in self.node_ids.keys() {
            set.insert(*node);
        }
        debug!("constraint graph has {} nodes", set.len());
        set.into_iter().collect()
    }
    fn edges(&self) -> dot::Edges<Edge<'tcx>> {
        debug!("constraint graph has {} edges", self.map.len());
        let mut v: Vec<_> = self.map.keys().map(|e| Edge::Constraint(*e)).collect();
        self.tcx.region_maps.each_encl_scope(|sub, sup| v.push(Edge::EnclScope(*sub, *sup)));
        debug!("region graph has {} edges", v.len());
        Cow::Owned(v)
    }
    fn source(&self, edge: &Edge<'tcx>) -> Node {
        let (n1, _) = edge_to_nodes(edge);
        debug!("edge {:?} has source {:?}", edge, n1);
        n1
    }
    fn target(&self, edge: &Edge<'tcx>) -> Node {
        let (_, n2) = edge_to_nodes(edge);
        debug!("edge {:?} has target {:?}", edge, n2);
        n2
    }
}

pub type ConstraintMap<'tcx> = FxHashMap<Constraint<'tcx>, SubregionOrigin<'tcx>>;

fn dump_region_constraints_to<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
                                              map: &ConstraintMap<'tcx>,
                                              path: &str)
                                              -> io::Result<()> {
    debug!("dump_region_constraints map (len: {}) path: {}",
           map.len(),
           path);
    let g = ConstraintGraph::new(tcx, format!("region_constraints"), map);
    debug!("dump_region_constraints calling render");
    let mut v = Vec::new();
    dot::render(&g, &mut v).unwrap();
    File::create(path).and_then(|mut f| f.write_all(&v))
}
<commit_msg>Dont bug! on user error<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! This module provides linkage between libgraphviz traits and
//! `rustc::middle::typeck::infer::region_inference`, generating a
//! rendering of the graph represented by the list of `Constraint`
//! instances (which make up the edges of the graph), as well as the
//! origin for each constraint (which are attached to the labels on
//! each edge).

/// For clarity, rename the graphviz crate locally to dot.
use graphviz as dot;

use ty::{self, TyCtxt};
use middle::region::CodeExtent;
use super::Constraint;
use infer::SubregionOrigin;
use infer::region_inference::RegionVarBindings;
use util::nodemap::{FxHashMap, FxHashSet};

use std::borrow::Cow;
use std::collections::hash_map::Entry::Vacant;
use std::env;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::sync::atomic::{AtomicBool, Ordering};
use syntax::ast;

fn print_help_message() {
    println!("\
-Z print-region-graph by default prints a region constraint graph for every \n\
function body, to the path `/tmp/constraints.nodeXXX.dot`, where the XXX is \n\
replaced with the node id of the function under analysis.                   \n\
                                                                            \n\
To select one particular function body, set `RUST_REGION_GRAPH_NODE=XXX`,   \n\
where XXX is the node id desired.                                           \n\
                                                                            \n\
To generate output to some path other than the default                      \n\
`/tmp/constraints.nodeXXX.dot`, set `RUST_REGION_GRAPH=/path/desired.dot`;  \n\
occurrences of the character `%` in the requested path will be replaced with\n\
the node id of the function under analysis.                                 \n\
                                                                            \n\
(Since you requested help via RUST_REGION_GRAPH=help, no region constraint  \n\
graphs will be printed.                                                     \n\
");
}

pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
    region_vars: &RegionVarBindings<'a, 'gcx, 'tcx>,
    subject_node: ast::NodeId)
{
    let tcx = region_vars.tcx;

    if !region_vars.tcx.sess.opts.debugging_opts.print_region_graph {
        return;
    }

    let requested_node = env::var("RUST_REGION_GRAPH_NODE")
        .ok().and_then(|s| s.parse().map(ast::NodeId::new).ok());

    if requested_node.is_some() && requested_node != Some(subject_node) {
        return;
    }

    let requested_output = env::var("RUST_REGION_GRAPH");
    debug!("requested_output: {:?} requested_node: {:?}",
           requested_output,
           requested_node);

    let output_path = {
        let output_template = match requested_output {
            Ok(ref s) if s == "help" => {
                static PRINTED_YET: AtomicBool = AtomicBool::new(false);
                if !PRINTED_YET.load(Ordering::SeqCst) {
                    print_help_message();
                    PRINTED_YET.store(true, Ordering::SeqCst);
                }
                return;
            }

            Ok(other_path) => other_path,
            Err(_) => "/tmp/constraints.node%.dot".to_string(),
        };

        if output_template.is_empty() {
            panic!("empty string provided as RUST_REGION_GRAPH");
        }

        if output_template.contains('%') {
            let mut new_str = String::new();
            for c in output_template.chars() {
                if c == '%' {
                    new_str.push_str(&subject_node.to_string());
                } else {
                    new_str.push(c);
                }
            }
            new_str
        } else {
            output_template
        }
    };

    let constraints = &*region_vars.constraints.borrow();
    match dump_region_constraints_to(tcx, constraints, &output_path) {
        Ok(()) => {}
        Err(e) => {
            let msg = format!("io error dumping region constraints: {}", e);
            region_vars.tcx.sess.err(&msg)
        }
    }
}

struct ConstraintGraph<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
    tcx: TyCtxt<'a, 'gcx, 'tcx>,
    graph_name: String,
    map: &'a FxHashMap<Constraint<'tcx>, SubregionOrigin<'tcx>>,
    node_ids: FxHashMap<Node, usize>,
}

#[derive(Clone, Hash, PartialEq, Eq, Debug, Copy)]
enum Node {
    RegionVid(ty::RegionVid),
    Region(ty::Region),
}

// type Edge = Constraint;
#[derive(Clone, PartialEq, Eq, Debug, Copy)]
enum Edge<'tcx> {
    Constraint(Constraint<'tcx>),
    EnclScope(CodeExtent, CodeExtent),
}

impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> {
    fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
           name: String,
           map: &'a ConstraintMap<'tcx>)
           -> ConstraintGraph<'a, 'gcx, 'tcx> {
        let mut i = 0;
        let mut node_ids = FxHashMap();
        {
            let mut add_node = |node| {
                if let Vacant(e) = node_ids.entry(node) {
                    e.insert(i);
                    i += 1;
                }
            };

            for (n1, n2) in map.keys().map(|c| constraint_to_nodes(c)) {
                add_node(n1);
                add_node(n2);
            }

            tcx.region_maps.each_encl_scope(|sub, sup| {
                add_node(Node::Region(ty::ReScope(*sub)));
                add_node(Node::Region(ty::ReScope(*sup)));
            });
        }

        ConstraintGraph {
            tcx: tcx,
            graph_name: name,
            map: map,
            node_ids: node_ids,
        }
    }
}

impl<'a, 'gcx, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
    type Node = Node;
    type Edge = Edge<'tcx>;
    fn graph_id(&self) -> dot::Id {
        dot::Id::new(&*self.graph_name).unwrap()
    }
    fn node_id(&self, n: &Node) -> dot::Id {
        let node_id = match self.node_ids.get(n) {
            Some(node_id) => node_id,
            None => bug!("no node_id found for node: {:?}", n),
        };
        let name = || format!("node_{}", node_id);
        match dot::Id::new(name()) {
            Ok(id) => id,
            Err(_) => {
                bug!("failed to create graphviz node identified by {}", name());
            }
        }
    }
    fn node_label(&self, n: &Node) -> dot::LabelText {
        match *n {
            Node::RegionVid(n_vid) => dot::LabelText::label(format!("{:?}", n_vid)),
            Node::Region(n_rgn) => dot::LabelText::label(format!("{:?}", n_rgn)),
        }
    }
    fn edge_label(&self, e: &Edge) -> dot::LabelText {
        match *e {
            Edge::Constraint(ref c) =>
                dot::LabelText::label(format!("{:?}", self.map.get(c).unwrap())),
            Edge::EnclScope(..) => dot::LabelText::label(format!("(enclosed)")),
        }
    }
}

fn constraint_to_nodes(c: &Constraint) -> (Node, Node) {
    match *c {
        Constraint::ConstrainVarSubVar(rv_1, rv_2) =>
            (Node::RegionVid(rv_1), Node::RegionVid(rv_2)),
        Constraint::ConstrainRegSubVar(r_1, rv_2) =>
            (Node::Region(*r_1), Node::RegionVid(rv_2)),
        Constraint::ConstrainVarSubReg(rv_1, r_2) =>
            (Node::RegionVid(rv_1), Node::Region(*r_2)),
        Constraint::ConstrainRegSubReg(r_1, r_2) =>
            (Node::Region(*r_1), Node::Region(*r_2)),
    }
}

fn edge_to_nodes(e: &Edge) -> (Node, Node) {
    match *e {
        Edge::Constraint(ref c) => constraint_to_nodes(c),
        Edge::EnclScope(sub, sup) => {
            (Node::Region(ty::ReScope(sub)),
             Node::Region(ty::ReScope(sup)))
        }
    }
}

impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
    type Node = Node;
    type Edge = Edge<'tcx>;
    fn nodes(&self) -> dot::Nodes<Node> {
        let mut set = FxHashSet();
        for node in self.node_ids.keys() {
            set.insert(*node);
        }
        debug!("constraint graph has {} nodes", set.len());
        set.into_iter().collect()
    }
    fn edges(&self) -> dot::Edges<Edge<'tcx>> {
        debug!("constraint graph has {} edges", self.map.len());
        let mut v: Vec<_> = self.map.keys().map(|e| Edge::Constraint(*e)).collect();
        self.tcx.region_maps.each_encl_scope(|sub, sup| v.push(Edge::EnclScope(*sub, *sup)));
        debug!("region graph has {} edges", v.len());
        Cow::Owned(v)
    }
    fn source(&self, edge: &Edge<'tcx>) -> Node {
        let (n1, _) = edge_to_nodes(edge);
        debug!("edge {:?} has source {:?}", edge, n1);
        n1
    }
    fn target(&self, edge: &Edge<'tcx>) -> Node {
        let (_, n2) = edge_to_nodes(edge);
        debug!("edge {:?} has target {:?}", edge, n2);
        n2
    }
}

pub type ConstraintMap<'tcx> = FxHashMap<Constraint<'tcx>, SubregionOrigin<'tcx>>;

fn dump_region_constraints_to<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
                                              map: &ConstraintMap<'tcx>,
                                              path: &str)
                                              -> io::Result<()> {
    debug!("dump_region_constraints map (len: {}) path: {}",
           map.len(),
           path);
    let g = ConstraintGraph::new(tcx, format!("region_constraints"), map);
    debug!("dump_region_constraints calling render");
    let mut v = Vec::new();
    dot::render(&g, &mut v).unwrap();
    File::create(path).and_then(|mut f| f.write_all(&v))
}
<|endoftext|>


<commit_before>// xfail-pretty

fn id(x: bool) -> bool { x }

fn call_id() {
    let c <- fail;
    id(c);
}

fn call_id_2() { id(true) && id(ret); }

fn call_id_3() { id(ret) && id(ret); }

fn call_id_4() { while id(break) { } }

iter put_break() -> int {
    while true { put break; }
}

fn fail_fail() { fail fail; }

fn log_fail() { log_err fail; }

fn log_ret() { log_err ret; }

fn log_break() { while true { log_err break; } }

fn log_cont() { do { log_err cont; } while false }

fn ret_ret() -> int { ret (ret 2) + 3; }

fn ret_guard() {
    alt 2 {
      x when (ret) { x; }
    }
}

fn fail_then_concat() {
    let x = [], y = [3];
    fail;
    x += y;
    "good" + "bye";
}

fn main() {}
<commit_msg>Test for #973<commit_after>// xfail-pretty

fn id(x: bool) -> bool { x }

fn call_id() {
    let c <- fail;
    id(c);
}

fn call_id_2() { id(true) && id(ret); }

fn call_id_3() { id(ret) && id(ret); }

fn call_id_4() { while id(break) { } }

fn bind_id_1() { bind id(fail); }

fn bind_id_2() { bind id(ret); }

iter put_break() -> int {
    while true { put break; }
}

fn fail_fail() { fail fail; }

fn log_fail() { log_err fail; }

fn log_ret() { log_err ret; }

fn log_break() { while true { log_err break; } }

fn log_cont() { do { log_err cont; } while false }

fn ret_ret() -> int { ret (ret 2) + 3; }

fn ret_guard() {
    alt 2 {
      x when (ret) { x; }
    }
}

fn fail_then_concat() {
    let x = [], y = [3];
    fail;
    x += y;
    "good" + "bye";
}

fn main() {}
<|endoftext|>


<commit_before>use super::canvas::{Canvas, Image, FONT_W};
use super::{WidgetId};
use ::{V2, Rect, ToColor, color};
use ::Anchor::*;

/// Helper methods for canvas context that do not depend on the underlying
/// implementation details.
pub trait CanvasUtil {
    /// Draw a thick solid line on the canvas.
    fn draw_line<C: ToColor+Copy>(&mut self, width: f32, p1: V2<f32>, p2: V2<f32>, layer: f32, color: &C);
    /// Get the size of an atlas image.
    fn image_dim(&self, img: Image) -> V2<u32>;

    /// Draw a stored image on the canvas.
    fn draw_image<C: ToColor+Copy, D: ToColor+Copy>(&mut self, img: Image,
        offset: V2<f32>, z: f32, color: &C, back_color: &D);

    /// Draw a filled rectangle
    fn fill_rect<C: ToColor+Copy>(&mut self, rect: &Rect<f32>, z: f32, color: &C);

    // TODO: More specs
    fn button(&mut self, id: WidgetId, pos: V2<f32>, z: f32) -> bool;

    fn draw_char<C: ToColor+Copy, D: ToColor+Copy>(&mut self, c: char, offset: V2<f32>, z: f32, color: &C, border: Option<&D>);

    fn char_width(&self, c: char) -> f32;
}

impl<'a> CanvasUtil for Canvas<'a> {
    fn draw_line<C: ToColor+Copy>(&mut self, width: f32, p1: V2<f32>, p2: V2<f32>, layer: f32, color: &C) {
        if p1 == p2 { return; }

        let tex = self.solid_tex_coord();

        // The front vector. Extend by width.
        let v1 = p2 - p1;
        let scalar = v1.dot(v1);
        let scalar = (scalar + width * width) / scalar;
        let v1 = v1 * scalar;

        // The sideways vector, turn into unit vector, then multiply by half the width.
        let v2 = V2(-v1.1, v1.0);
        let scalar = width / 2.0 * 1.0 / v2.dot(v2).sqrt();
        let v2 = v2 * scalar;

        let ind0 = self.num_vertices();
        self.push_vertex(p1 + v2, layer, tex, color, &color::BLACK);
        self.push_vertex(p1 - v2, layer, tex, color, &color::BLACK);
        self.push_vertex(p1 - v2 + v1, layer, tex, color, &color::BLACK);
        self.push_vertex(p1 + v2 + v1, layer, tex, color, &color::BLACK);
        self.push_triangle(ind0, ind0 + 1, ind0 + 2);
        self.push_triangle(ind0, ind0 + 2, ind0 + 3);
    }

    fn image_dim(&self, img: Image) -> V2<u32> {
        self.image_data(img).pos.1.map(|x| x as u32)
    }

    fn draw_image<C: ToColor+Copy, D: ToColor+Copy>(&mut self, img: Image,
        offset: V2<f32>, z: f32, color: &C, back_color: &D) {
        // Use round numbers, fractions seem to cause artifacts to pixels.
        let offset = offset.map(|x| x.floor());
        let mut pos;
        let mut tex;
        {
            let data = self.image_data(img);
            pos = data.pos + offset;
            tex = data.tex;
        }

        let ind0 = self.num_vertices();

        self.push_vertex(pos.point(TopLeft), z, tex.point(TopLeft), color, back_color);
        self.push_vertex(pos.point(TopRight), z, tex.point(TopRight), color, back_color);
        self.push_vertex(pos.point(BottomRight), z, tex.point(BottomRight), color, back_color);
        self.push_vertex(pos.point(BottomLeft), z, tex.point(BottomLeft), color, back_color);

        self.push_triangle(ind0, ind0 + 1, ind0 + 2);
        self.push_triangle(ind0, ind0 + 2, ind0 + 3);
    }

    fn fill_rect<C: ToColor+Copy>(&mut self, rect: &Rect<f32>, z: f32, color: &C) {
        let tex = self.solid_tex_coord();
        let ind0 = self.num_vertices();

        self.push_vertex(rect.point(TopLeft), z, tex, color, &color::BLACK);
        self.push_vertex(rect.point(TopRight), z, tex, color, &color::BLACK);
        self.push_vertex(rect.point(BottomRight), z, tex, color, &color::BLACK);
        self.push_vertex(rect.point(BottomLeft), z, tex, color, &color::BLACK);

        self.push_triangle(ind0, ind0 + 1, ind0 + 2);
        self.push_triangle(ind0, ind0 + 2, ind0 + 3);
    }

    fn button(&mut self, id: WidgetId, pos: V2<f32>, z: f32) -> bool {
        // TODO: Button visual style! Closures?
        let area = Rect(pos, V2(64.0, 16.0));
        let mut color = color::GREEN;
        if area.contains(&self.mouse_pos) {
            self.hot_widget = Some(id);
            if self.active_widget.is_none() && self.mouse_pressed {
                self.active_widget = Some(id);
            }
            color = color::RED;
        }

        self.fill_rect(&area, z, &color);

        return !self.mouse_pressed // Mouse is released
            && self.active_widget == Some(id) // But this button is hot and active
            && self.hot_widget == Some(id);
    }

    fn draw_char<C: ToColor+Copy, D: ToColor+Copy>(&mut self, c: char, offset: V2<f32>, z: f32, color: &C, border: Option<&D>) {
        static BORDER: [V2<f32>; 8] =
            [V2(-1.0, -1.0), V2( 0.0, -1.0), V2( 1.0, -1.0),
             V2(-1.0,  0.0),                 V2( 1.0,  0.0),
             V2(-1.0,  1.0), V2( 0.0,  1.0), V2( 1.0,  1.0)];
        if let Some(img) = self.font_image(c) {
            if let Some(b) = border {
                // Put the border a tiny bit further in the z-buffer so it
                // won't clobber the text on the same layer.
                let border_z = z + 0.00001;
                for &d in BORDER.iter() {
                    self.draw_image(img, offset + d, border_z, b, &color::BLACK);
                }
            }
            self.draw_image(img, offset, z, color, &color::BLACK);
        }
    }

    fn char_width(&self, c: char) -> f32 {
        // Special case for space, the atlas image won't have a width.
        if c == ' ' { return (FONT_W / 2) as f32; }

        // Infer letter width from the cropped atlas image. (Use mx instead of
        // dim on the pos rectangle so that the left-side space will be
        // preserved and the letters are kept slightly apart.)
        if let Some(img) = self.font_image(c) {
            let width = self.image_data(img).pos.mx().0;
            return width;
        }

        // Not a valid letter.
        (FONT_W / 2) as f32
    }
}
<commit_msg>Wireframe rectangle<commit_after>use super::canvas::{Canvas, Image, FONT_W};
use super::{WidgetId};
use ::{V2, Rect, ToColor, color};
use ::Anchor::*;

/// Helper methods for canvas context that do not depend on the underlying
/// implementation details.
pub trait CanvasUtil {
    /// Draw a thick solid line on the canvas.
    fn draw_line<C: ToColor+Copy>(&mut self, width: f32, p1: V2<f32>, p2: V2<f32>, layer: f32, color: &C);
    /// Get the size of an atlas image.
    fn image_dim(&self, img: Image) -> V2<u32>;

    /// Draw a stored image on the canvas.
    fn draw_image<C: ToColor+Copy, D: ToColor+Copy>(&mut self, img: Image,
        offset: V2<f32>, z: f32, color: &C, back_color: &D);

    /// Draw a filled rectangle
    fn fill_rect<C: ToColor+Copy>(&mut self, rect: &Rect<f32>, z: f32, color: &C);

    /// Draw a wireframe rectangle
    fn draw_rect<C: ToColor+Copy>(&mut self, rect: &Rect<f32>, z: f32, color: &C);

    // TODO: More specs
    fn button(&mut self, id: WidgetId, pos: V2<f32>, z: f32) -> bool;

    fn draw_char<C: ToColor+Copy, D: ToColor+Copy>(&mut self, c: char, offset: V2<f32>, z: f32, color: &C, border: Option<&D>);

    fn char_width(&self, c: char) -> f32;
}

impl<'a> CanvasUtil for Canvas<'a> {
    fn draw_line<C: ToColor+Copy>(&mut self, width: f32, p1: V2<f32>, p2: V2<f32>, layer: f32, color: &C) {
        if p1 == p2 { return; }

        let tex = self.solid_tex_coord();

        // The front vector. Extend by width.
        let v1 = p2 - p1;
        let scalar = v1.dot(v1);
        let scalar = (scalar + width * width) / scalar;
        let v1 = v1 * scalar;

        // The sideways vector, turn into unit vector, then multiply by half the width.
        let v2 = V2(-v1.1, v1.0);
        let scalar = width / 2.0 * 1.0 / v2.dot(v2).sqrt();
        let v2 = v2 * scalar;

        let ind0 = self.num_vertices();
        self.push_vertex(p1 + v2, layer, tex, color, &color::BLACK);
        self.push_vertex(p1 - v2, layer, tex, color, &color::BLACK);
        self.push_vertex(p1 - v2 + v1, layer, tex, color, &color::BLACK);
        self.push_vertex(p1 + v2 + v1, layer, tex, color, &color::BLACK);
        self.push_triangle(ind0, ind0 + 1, ind0 + 2);
        self.push_triangle(ind0, ind0 + 2, ind0 + 3);
    }

    fn image_dim(&self, img: Image) -> V2<u32> {
        self.image_data(img).pos.1.map(|x| x as u32)
    }

    fn draw_image<C: ToColor+Copy, D: ToColor+Copy>(&mut self, img: Image,
        offset: V2<f32>, z: f32, color: &C, back_color: &D) {
        // Use round numbers, fractions seem to cause artifacts to pixels.
        let offset = offset.map(|x| x.floor());
        let mut pos;
        let mut tex;
        {
            let data = self.image_data(img);
            pos = data.pos + offset;
            tex = data.tex;
        }

        let ind0 = self.num_vertices();

        self.push_vertex(pos.point(TopLeft), z, tex.point(TopLeft), color, back_color);
        self.push_vertex(pos.point(TopRight), z, tex.point(TopRight), color, back_color);
        self.push_vertex(pos.point(BottomRight), z, tex.point(BottomRight), color, back_color);
        self.push_vertex(pos.point(BottomLeft), z, tex.point(BottomLeft), color, back_color);

        self.push_triangle(ind0, ind0 + 1, ind0 + 2);
        self.push_triangle(ind0, ind0 + 2, ind0 + 3);
    }

    fn fill_rect<C: ToColor+Copy>(&mut self, rect: &Rect<f32>, z: f32, color: &C) {
        let tex = self.solid_tex_coord();
        let ind0 = self.num_vertices();

        self.push_vertex(rect.point(TopLeft), z, tex, color, &color::BLACK);
        self.push_vertex(rect.point(TopRight), z, tex, color, &color::BLACK);
        self.push_vertex(rect.point(BottomRight), z, tex, color, &color::BLACK);
        self.push_vertex(rect.point(BottomLeft), z, tex, color, &color::BLACK);

        self.push_triangle(ind0, ind0 + 1, ind0 + 2);
        self.push_triangle(ind0, ind0 + 2, ind0 + 3);
    }

    fn draw_rect<C: ToColor+Copy>(&mut self, rect: &Rect<f32>, z: f32, color: &C) {
        self.draw_line(1.0, rect.point(TopLeft), rect.point(TopRight) - V2(1.0, 0.0), z, color);
        self.draw_line(1.0, rect.point(TopRight) - V2(1.0, 0.0), rect.point(BottomRight) - V2(1.0, 0.0), z, color);
        self.draw_line(1.0, rect.point(BottomLeft) - V2(0.0, 1.0), rect.point(BottomRight) - V2(1.0, 1.0), z, color);
        self.draw_line(1.0, rect.point(TopLeft), rect.point(BottomLeft), z, color);
    }

    fn button(&mut self, id: WidgetId, pos: V2<f32>, z: f32) -> bool {
        // TODO: Button visual style! Closures?
        let area = Rect(pos, V2(64.0, 16.0));
        let mut color = color::GREEN;
        if area.contains(&self.mouse_pos) {
            self.hot_widget = Some(id);
            if self.active_widget.is_none() && self.mouse_pressed {
                self.active_widget = Some(id);
            }
            color = color::RED;
        }

        self.fill_rect(&area, z, &color);

        return !self.mouse_pressed // Mouse is released
            && self.active_widget == Some(id) // But this button is hot and active
            && self.hot_widget == Some(id);
    }

    fn draw_char<C: ToColor+Copy, D: ToColor+Copy>(&mut self, c: char, offset: V2<f32>, z: f32, color: &C, border: Option<&D>) {
        static BORDER: [V2<f32>; 8] =
            [V2(-1.0, -1.0), V2( 0.0, -1.0), V2( 1.0, -1.0),
             V2(-1.0,  0.0),                 V2( 1.0,  0.0),
             V2(-1.0,  1.0), V2( 0.0,  1.0), V2( 1.0,  1.0)];
        if let Some(img) = self.font_image(c) {
            if let Some(b) = border {
                // Put the border a tiny bit further in the z-buffer so it
                // won't clobber the text on the same layer.
                let border_z = z + 0.00001;
                for &d in BORDER.iter() {
                    self.draw_image(img, offset + d, border_z, b, &color::BLACK);
                }
            }
            self.draw_image(img, offset, z, color, &color::BLACK);
        }
    }

    fn char_width(&self, c: char) -> f32 {
        // Special case for space, the atlas image won't have a width.
        if c == ' ' { return (FONT_W / 2) as f32; }

        // Infer letter width from the cropped atlas image. (Use mx instead of
        // dim on the pos rectangle so that the left-side space will be
        // preserved and the letters are kept slightly apart.)
        if let Some(img) = self.font_image(c) {
            let width = self.image_data(img).pos.mx().0;
            return width;
        }

        // Not a valid letter.
        (FONT_W / 2) as f32
    }
}
<|endoftext|>


<commit_before>use crate::native::VertexAttribFunction;
use hal::{format::Format, image as i, pso};

/*
pub fn _image_kind_to_gl(kind: i::Kind) -> t::GLenum {
    match kind {
        i::Kind::D1(_) => glow::TEXTURE_1D,
        i::Kind::D1Array(_, _) => glow::TEXTURE_1D_ARRAY,
        i::Kind::D2(_, _, i::AaMode::Single) => glow::TEXTURE_2D,
        i::Kind::D2(_, _, _) => glow::TEXTURE_2D_MULTISAMPLE,
        i::Kind::D2Array(_, _, _, i::AaMode::Single) => glow::TEXTURE_2D_ARRAY,
        i::Kind::D2Array(_, _, _, _) => glow::TEXTURE_2D_MULTISAMPLE_ARRAY,
        i::Kind::D3(_, _, _) => glow::TEXTURE_3D,
        i::Kind::Cube(_) => glow::TEXTURE_CUBE_MAP,
        i::Kind::CubeArray(_, _) => glow::TEXTURE_CUBE_MAP_ARRAY,
    }
}*/

pub fn filter_to_gl(mag: i::Filter, min: i::Filter, mip: i::Filter) -> (u32, u32) {
    use hal::image::Filter::*;

    let mag_filter = match mag {
        Nearest => glow::NEAREST,
        Linear => glow::LINEAR,
    };

    let min_filter = match (min, mip) {
        (Nearest, Nearest) => glow::NEAREST_MIPMAP_NEAREST,
        (Nearest, Linear) => glow::NEAREST_MIPMAP_LINEAR,
        (Linear, Nearest) => glow::LINEAR_MIPMAP_NEAREST,
        (Linear, Linear) => glow::LINEAR_MIPMAP_LINEAR,
    };

    (min_filter, mag_filter)
}

pub fn wrap_to_gl(w: i::WrapMode) -> u32 {
    match w {
        i::WrapMode::Tile => glow::REPEAT,
        i::WrapMode::Mirror => glow::MIRRORED_REPEAT,
        i::WrapMode::Clamp => glow::CLAMP_TO_EDGE,
        i::WrapMode::Border => glow::CLAMP_TO_BORDER,
        i::WrapMode::MirrorClamp => glow::MIRROR_CLAMP_TO_EDGE,
    }
}

pub fn input_assember_to_gl_primitive(ia: &pso::InputAssemblerDesc) -> u32 {
    match (ia.primitive, ia.with_adjacency) {
        (pso::Primitive::PointList, false) => glow::POINTS,
        (pso::Primitive::PointList, true) => panic!("Points can't have adjacency info"),
        (pso::Primitive::LineList, false) => glow::LINES,
        (pso::Primitive::LineList, true) => glow::LINES_ADJACENCY,
        (pso::Primitive::LineStrip, false) => glow::LINE_STRIP,
        (pso::Primitive::LineStrip, true) => glow::LINE_STRIP_ADJACENCY,
        (pso::Primitive::TriangleList, false) => glow::TRIANGLES,
        (pso::Primitive::TriangleList, true) => glow::TRIANGLES_ADJACENCY,
        (pso::Primitive::TriangleStrip, false) => glow::TRIANGLE_STRIP,
        (pso::Primitive::TriangleStrip, true) => glow::TRIANGLE_STRIP_ADJACENCY,
        (pso::Primitive::PatchList(_), false) => glow::PATCHES,
        (pso::Primitive::PatchList(_), true) => panic!("Patches can't have adjacency info"),
    }
}

pub struct FormatDescription {
    pub tex_internal: u32,
    pub tex_external: u32,
    pub data_type: u32,
    pub num_components: u8,
    pub va_fun: VertexAttribFunction,
}

impl FormatDescription {
    fn new(
        tex_internal: u32,
        tex_external: u32,
        data_type: u32,
        num_components: u8,
        va_fun: VertexAttribFunction,
    ) -> Self {
        FormatDescription {
            tex_internal,
            tex_external,
            data_type,
            num_components,
            va_fun,
        }
    }
}

pub fn describe_format(format: Format) -> Option<FormatDescription> {
    use crate::native::VertexAttribFunction::*;
    use hal::format::Format::*;
    let _ = Double; //mark as used

    // TODO: Add more formats and error handling for `None`
    Some(match format {
        R8Uint => FormatDescription::new(
            glow::R8UI,
            glow::RED_INTEGER,
            glow::UNSIGNED_BYTE,
            1,
            Integer,
        ),
        R8Sint => FormatDescription::new(glow::R8I, glow::RED_INTEGER, glow::BYTE, 1, Integer),
        R8Unorm => FormatDescription::new(glow::R8, glow::RED, glow::UNSIGNED_BYTE, 1, Float),
        Rg8Uint => FormatDescription::new(
            glow::RG8UI,
            glow::RG_INTEGER,
            glow::UNSIGNED_BYTE,
            2,
            Integer,
        ),
        Rg8Sint => FormatDescription::new(glow::RG8I, glow::RG_INTEGER, glow::BYTE, 2, Integer),
        Rgba8Uint => FormatDescription::new(
            glow::RGBA8UI,
            glow::RGBA_INTEGER,
            glow::UNSIGNED_BYTE,
            4,
            Integer,
        ),
        Rgba8Sint => {
            FormatDescription::new(glow::RGBA8I, glow::RGBA_INTEGER, glow::BYTE, 4, Integer)
        }
        Rgba8Unorm => {
            FormatDescription::new(glow::RGBA8, glow::RGBA, glow::UNSIGNED_BYTE, 4, Float)
        }
        Rgb8Srgb => FormatDescription::new(glow::SRGB8, glow::RGB, glow::UNSIGNED_BYTE, 3, Float),
        Rgba8Srgb => FormatDescription::new(
            glow::SRGB8_ALPHA8,
            glow::RGBA,
            glow::UNSIGNED_BYTE,
            4,
            Float,
        ),
        Bgra8Unorm => {
            FormatDescription::new(glow::RGBA8, glow::BGRA, glow::UNSIGNED_BYTE, 4, Float)
        }
        Bgra8Srgb => FormatDescription::new(
            glow::SRGB8_ALPHA8,
            glow::BGRA,
            glow::UNSIGNED_BYTE,
            4,
            Float,
        ),
        R16Uint => FormatDescription::new(
            glow::R16UI,
            glow::RED_INTEGER,
            glow::UNSIGNED_SHORT,
            1,
            Integer,
        ),
        R16Sint => FormatDescription::new(glow::R16I, glow::RED_INTEGER, glow::SHORT, 1, Integer),
        R16Sfloat => FormatDescription::new(glow::R16, glow::RED, glow::HALF_FLOAT, 1, Float),
        R16Unorm => FormatDescription::new(glow::R16, glow::RED, glow::UNSIGNED_SHORT, 1, Float),
        Rg16Uint => FormatDescription::new(
            glow::RG16UI,
            glow::RG_INTEGER,
            glow::UNSIGNED_SHORT,
            2,
            Integer,
        ),
        Rg16Sint => FormatDescription::new(glow::RG16I, glow::RG_INTEGER, glow::SHORT, 2, Integer),
        Rg16Unorm => FormatDescription::new(glow::RG16, glow::RG, glow::UNSIGNED_SHORT, 2, Float),
        Rg16Sfloat => FormatDescription::new(glow::RG16, glow::RG, glow::HALF_FLOAT, 2, Float),
        Rgba16Uint => FormatDescription::new(
            glow::RGBA16UI,
            glow::RGBA_INTEGER,
            glow::UNSIGNED_SHORT,
            4,
            Integer,
        ),
        Rgba16Sint => {
            FormatDescription::new(glow::RGBA16I, glow::RGBA_INTEGER, glow::SHORT, 4, Integer)
        }
        Rgba16Sfloat => {
            FormatDescription::new(glow::RGBA16, glow::RGBA, glow::HALF_FLOAT, 4, Float)
        }
        Rgba16Unorm => {
            FormatDescription::new(glow::RGBA16, glow::RGBA, glow::UNSIGNED_SHORT, 4, Float)
        }
        R32Uint => FormatDescription::new(
            glow::R32UI,
            glow::RED_INTEGER,
            glow::UNSIGNED_INT,
            1,
            Integer,
        ),
        R32Sint => FormatDescription::new(glow::R32I, glow::RED_INTEGER, glow::INT, 1, Integer),
        R32Sfloat => FormatDescription::new(glow::R32F, glow::RED, glow::FLOAT, 1, Float),
        Rg32Uint => FormatDescription::new(
            glow::RG32UI,
            glow::RG_INTEGER,
            glow::UNSIGNED_INT,
            2,
            Integer,
        ),
        Rg32Sint => FormatDescription::new(glow::R32I, glow::RG_INTEGER, glow::INT, 2, Integer),
        Rg32Sfloat => FormatDescription::new(glow::RG32F, glow::RG, glow::FLOAT, 2, Float),
        Rgb32Uint => FormatDescription::new(
            glow::RGB32UI,
            glow::RGB_INTEGER,
            glow::UNSIGNED_INT,
            3,
            Integer,
        ),
        Rgb32Sint => FormatDescription::new(glow::RGB32I, glow::RGB_INTEGER, glow::INT, 3, Integer),
        Rgb32Sfloat => FormatDescription::new(glow::RGB32F, glow::RGB, glow::FLOAT, 3, Float),
        Rgba32Uint => FormatDescription::new(
            glow::RGBA32UI,
            glow::RGBA_INTEGER,
            glow::UNSIGNED_INT,
            4,
            Integer,
        ),
        Rgba32Sint => {
            FormatDescription::new(glow::RGBA32I, glow::RGBA_INTEGER, glow::INT, 4, Integer)
        }
        Rgba32Sfloat => FormatDescription::new(glow::RGBA32F, glow::RGBA, glow::FLOAT, 4, Float),
        S8Uint => FormatDescription::new(glow::R8, glow::RED, glow::UNSIGNED_BYTE, 1, Integer),
        D16Unorm => FormatDescription::new(
            glow::DEPTH_COMPONENT16,
            glow::DEPTH_COMPONENT,
            glow::UNSIGNED_NORMALIZED,
            1,
            Float,
        ),
        D24UnormS8Uint => FormatDescription::new(
            glow::DEPTH24_STENCIL8,
            glow::DEPTH_STENCIL,
            glow::UNSIGNED_INT,
            2,
            Float,
        ),
        D32Sfloat => FormatDescription::new(
            glow::DEPTH_COMPONENT32F,
            glow::DEPTH_COMPONENT,
            glow::FLOAT,
            1,
            Float,
        ),
        D32SfloatS8Uint => FormatDescription::new(
            glow::DEPTH32F_STENCIL8,
            glow::DEPTH_STENCIL,
            glow::UNSIGNED_INT,
            1,
            Float,
        ),
        X8D24Unorm => FormatDescription::new(
            glow::DEPTH_COMPONENT24,
            glow::DEPTH_STENCIL,
            glow::UNSIGNED_NORMALIZED,
            2,
            Float,
        ),

        _ => return None,
    })
}

#[cfg(feature = "cross")]
pub fn map_naga_stage_to_cross(stage: naga::ShaderStage) -> spirv_cross::spirv::ExecutionModel {
    use spirv_cross::spirv::ExecutionModel as Em;
    match stage {
        naga::ShaderStage::Vertex => Em::Vertex,
        naga::ShaderStage::Fragment => Em::Fragment,
        naga::ShaderStage::Compute => Em::GlCompute,
    }
}
<commit_msg>Fix incorrect gl texture internal formats<commit_after>use crate::native::VertexAttribFunction;
use hal::{format::Format, image as i, pso};

/*
pub fn _image_kind_to_gl(kind: i::Kind) -> t::GLenum {
    match kind {
        i::Kind::D1(_) => glow::TEXTURE_1D,
        i::Kind::D1Array(_, _) => glow::TEXTURE_1D_ARRAY,
        i::Kind::D2(_, _, i::AaMode::Single) => glow::TEXTURE_2D,
        i::Kind::D2(_, _, _) => glow::TEXTURE_2D_MULTISAMPLE,
        i::Kind::D2Array(_, _, _, i::AaMode::Single) => glow::TEXTURE_2D_ARRAY,
        i::Kind::D2Array(_, _, _, _) => glow::TEXTURE_2D_MULTISAMPLE_ARRAY,
        i::Kind::D3(_, _, _) => glow::TEXTURE_3D,
        i::Kind::Cube(_) => glow::TEXTURE_CUBE_MAP,
        i::Kind::CubeArray(_, _) => glow::TEXTURE_CUBE_MAP_ARRAY,
    }
}*/

pub fn filter_to_gl(mag: i::Filter, min: i::Filter, mip: i::Filter) -> (u32, u32) {
    use hal::image::Filter::*;

    let mag_filter = match mag {
        Nearest => glow::NEAREST,
        Linear => glow::LINEAR,
    };

    let min_filter = match (min, mip) {
        (Nearest, Nearest) => glow::NEAREST_MIPMAP_NEAREST,
        (Nearest, Linear) => glow::NEAREST_MIPMAP_LINEAR,
        (Linear, Nearest) => glow::LINEAR_MIPMAP_NEAREST,
        (Linear, Linear) => glow::LINEAR_MIPMAP_LINEAR,
    };

    (min_filter, mag_filter)
}

pub fn wrap_to_gl(w: i::WrapMode) -> u32 {
    match w {
        i::WrapMode::Tile => glow::REPEAT,
        i::WrapMode::Mirror => glow::MIRRORED_REPEAT,
        i::WrapMode::Clamp => glow::CLAMP_TO_EDGE,
        i::WrapMode::Border => glow::CLAMP_TO_BORDER,
        i::WrapMode::MirrorClamp => glow::MIRROR_CLAMP_TO_EDGE,
    }
}

pub fn input_assember_to_gl_primitive(ia: &pso::InputAssemblerDesc) -> u32 {
    match (ia.primitive, ia.with_adjacency) {
        (pso::Primitive::PointList, false) => glow::POINTS,
        (pso::Primitive::PointList, true) => panic!("Points can't have adjacency info"),
        (pso::Primitive::LineList, false) => glow::LINES,
        (pso::Primitive::LineList, true) => glow::LINES_ADJACENCY,
        (pso::Primitive::LineStrip, false) => glow::LINE_STRIP,
        (pso::Primitive::LineStrip, true) => glow::LINE_STRIP_ADJACENCY,
        (pso::Primitive::TriangleList, false) => glow::TRIANGLES,
        (pso::Primitive::TriangleList, true) => glow::TRIANGLES_ADJACENCY,
        (pso::Primitive::TriangleStrip, false) => glow::TRIANGLE_STRIP,
        (pso::Primitive::TriangleStrip, true) => glow::TRIANGLE_STRIP_ADJACENCY,
        (pso::Primitive::PatchList(_), false) => glow::PATCHES,
        (pso::Primitive::PatchList(_), true) => panic!("Patches can't have adjacency info"),
    }
}

pub struct FormatDescription {
    pub tex_internal: u32,
    pub tex_external: u32,
    pub data_type: u32,
    pub num_components: u8,
    pub va_fun: VertexAttribFunction,
}

impl FormatDescription {
    fn new(
        tex_internal: u32,
        tex_external: u32,
        data_type: u32,
        num_components: u8,
        va_fun: VertexAttribFunction,
    ) -> Self {
        FormatDescription {
            tex_internal,
            tex_external,
            data_type,
            num_components,
            va_fun,
        }
    }
}

pub fn describe_format(format: Format) -> Option<FormatDescription> {
    use crate::native::VertexAttribFunction::*;
    use hal::format::Format::*;
    let _ = Double; //mark as used

    // TODO: Add more formats and error handling for `None`
    Some(match format {
        R8Uint => FormatDescription::new(
            glow::R8UI,
            glow::RED_INTEGER,
            glow::UNSIGNED_BYTE,
            1,
            Integer,
        ),
        R8Sint => FormatDescription::new(glow::R8I, glow::RED_INTEGER, glow::BYTE, 1, Integer),
        R8Unorm => FormatDescription::new(glow::R8, glow::RED, glow::UNSIGNED_BYTE, 1, Float),
        Rg8Uint => FormatDescription::new(
            glow::RG8UI,
            glow::RG_INTEGER,
            glow::UNSIGNED_BYTE,
            2,
            Integer,
        ),
        Rg8Sint => FormatDescription::new(glow::RG8I, glow::RG_INTEGER, glow::BYTE, 2, Integer),
        Rgba8Uint => FormatDescription::new(
            glow::RGBA8UI,
            glow::RGBA_INTEGER,
            glow::UNSIGNED_BYTE,
            4,
            Integer,
        ),
        Rgba8Sint => {
            FormatDescription::new(glow::RGBA8I, glow::RGBA_INTEGER, glow::BYTE, 4, Integer)
        }
        Rgba8Unorm => {
            FormatDescription::new(glow::RGBA8, glow::RGBA, glow::UNSIGNED_BYTE, 4, Float)
        }
        Rgb8Srgb => FormatDescription::new(glow::SRGB8, glow::RGB, glow::UNSIGNED_BYTE, 3, Float),
        Rgba8Srgb => FormatDescription::new(
            glow::SRGB8_ALPHA8,
            glow::RGBA,
            glow::UNSIGNED_BYTE,
            4,
            Float,
        ),
        Bgra8Unorm => FormatDescription::new(glow::BGRA, glow::BGRA, glow::UNSIGNED_BYTE, 4, Float),
        Bgra8Srgb => FormatDescription::new(
            glow::SRGB8_ALPHA8,
            glow::BGRA,
            glow::UNSIGNED_BYTE,
            4,
            Float,
        ),
        R16Uint => FormatDescription::new(
            glow::R16UI,
            glow::RED_INTEGER,
            glow::UNSIGNED_SHORT,
            1,
            Integer,
        ),
        R16Sint => FormatDescription::new(glow::R16I, glow::RED_INTEGER, glow::SHORT, 1, Integer),
        R16Sfloat => FormatDescription::new(glow::R16F, glow::RED, glow::HALF_FLOAT, 1, Float),
        R16Unorm => FormatDescription::new(glow::R16, glow::RED, glow::UNSIGNED_SHORT, 1, Float),
        Rg16Uint => FormatDescription::new(
            glow::RG16UI,
            glow::RG_INTEGER,
            glow::UNSIGNED_SHORT,
            2,
            Integer,
        ),
        Rg16Sint => FormatDescription::new(glow::RG16I, glow::RG_INTEGER, glow::SHORT, 2, Integer),
        Rg16Unorm => FormatDescription::new(glow::RG16, glow::RG, glow::UNSIGNED_SHORT, 2, Float),
        Rg16Sfloat => FormatDescription::new(glow::RG16F, glow::RG, glow::HALF_FLOAT, 2, Float),
        Rgba16Uint => FormatDescription::new(
            glow::RGBA16UI,
            glow::RGBA_INTEGER,
            glow::UNSIGNED_SHORT,
            4,
            Integer,
        ),
        Rgba16Sint => {
            FormatDescription::new(glow::RGBA16I, glow::RGBA_INTEGER, glow::SHORT, 4, Integer)
        }
        Rgba16Sfloat => {
            FormatDescription::new(glow::RGBA16F, glow::RGBA, glow::HALF_FLOAT, 4, Float)
        }
        Rgba16Unorm => {
            FormatDescription::new(glow::RGBA16, glow::RGBA, glow::UNSIGNED_SHORT, 4, Float)
        }
        R32Uint => FormatDescription::new(
            glow::R32UI,
            glow::RED_INTEGER,
            glow::UNSIGNED_INT,
            1,
            Integer,
        ),
        R32Sint => FormatDescription::new(glow::R32I, glow::RED_INTEGER, glow::INT, 1, Integer),
        R32Sfloat => FormatDescription::new(glow::R32F, glow::RED, glow::FLOAT, 1, Float),
        Rg32Uint => FormatDescription::new(
            glow::RG32UI,
            glow::RG_INTEGER,
            glow::UNSIGNED_INT,
            2,
            Integer,
        ),
        Rg32Sint => FormatDescription::new(glow::R32I, glow::RG_INTEGER, glow::INT, 2, Integer),
        Rg32Sfloat => FormatDescription::new(glow::RG32F, glow::RG, glow::FLOAT, 2, Float),
        Rgb32Uint => FormatDescription::new(
            glow::RGB32UI,
            glow::RGB_INTEGER,
            glow::UNSIGNED_INT,
            3,
            Integer,
        ),
        Rgb32Sint => FormatDescription::new(glow::RGB32I, glow::RGB_INTEGER, glow::INT, 3, Integer),
        Rgb32Sfloat => FormatDescription::new(glow::RGB32F, glow::RGB, glow::FLOAT, 3, Float),
        Rgba32Uint => FormatDescription::new(
            glow::RGBA32UI,
            glow::RGBA_INTEGER,
            glow::UNSIGNED_INT,
            4,
            Integer,
        ),
        Rgba32Sint => {
            FormatDescription::new(glow::RGBA32I, glow::RGBA_INTEGER, glow::INT, 4, Integer)
        }
        Rgba32Sfloat => FormatDescription::new(glow::RGBA32F, glow::RGBA, glow::FLOAT, 4, Float),
        S8Uint => FormatDescription::new(glow::R8, glow::RED, glow::UNSIGNED_BYTE, 1, Integer),
        D16Unorm => FormatDescription::new(
            glow::DEPTH_COMPONENT16,
            glow::DEPTH_COMPONENT,
            glow::UNSIGNED_NORMALIZED,
            1,
            Float,
        ),
        D24UnormS8Uint => FormatDescription::new(
            glow::DEPTH24_STENCIL8,
            glow::DEPTH_STENCIL,
            glow::UNSIGNED_INT,
            2,
            Float,
        ),
        D32Sfloat => FormatDescription::new(
            glow::DEPTH_COMPONENT32F,
            glow::DEPTH_COMPONENT,
            glow::FLOAT,
            1,
            Float,
        ),
        D32SfloatS8Uint => FormatDescription::new(
            glow::DEPTH32F_STENCIL8,
            glow::DEPTH_STENCIL,
            glow::UNSIGNED_INT,
            1,
            Float,
        ),
        X8D24Unorm => FormatDescription::new(
            glow::DEPTH_COMPONENT24,
            glow::DEPTH_STENCIL,
            glow::UNSIGNED_NORMALIZED,
            2,
            Float,
        ),

        _ => return None,
    })
}

#[cfg(feature = "cross")]
pub fn map_naga_stage_to_cross(stage: naga::ShaderStage) -> spirv_cross::spirv::ExecutionModel {
    use spirv_cross::spirv::ExecutionModel as Em;
    match stage {
        naga::ShaderStage::Vertex => Em::Vertex,
        naga::ShaderStage::Fragment => Em::Fragment,
        naga::ShaderStage::Compute => Em::GlCompute,
    }
}
<|endoftext|>


<commit_before>use std::str::{from_utf8};

extern crate rustc_serialize;
use rustc_serialize::hex::{FromHex, ToHex};

fn main() {
	let a = "1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736".from_hex().unwrap();

	let mut vec: Vec<u8> = Vec::new();
	for _ in 0..a.len() {
		vec.push(0);
	}

	for char in 0..255 {
		for i in 0..a.len() {
			vec[i] = a[i] ^ char;
		}
		match from_utf8(&vec) {
			Ok(v) => {
				println!("{}", v);
			}
            Err(e) => {}
		}
	}
}
<commit_msg>set1 challenge3: skip strings with unprintable characters<commit_after>use std::str::{from_utf8};

extern crate rustc_serialize;
use rustc_serialize::hex::{FromHex};

fn main() {
	let a = "1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736".from_hex().unwrap();

	let mut vec: Vec<u8> = Vec::new();
	for _ in 0..a.len() {
		vec.push(0);
	}

	'char_loop: for char in 0..255 {
		for i in 0..a.len() {
			match a[i] ^ char {
				0x20...0x7E => {
					vec[i] = a[i] ^ char;
				}
				_ => {
					continue 'char_loop;
				}
			}
		}
		match from_utf8(&vec) {
			Ok(v) => {
				println!("{}", v);
			}
            _ => {}
		}
	}
}
<|endoftext|>


<commit_before>use core::mem::size_of;

use bits32::task::*;
use shared::descriptor;
use shared::PrivilegeLevel;
pub use shared::segmentation::*;

/// Reload code segment register.
/// Note this is special since we can not directly move
/// to %cs. Instead we push the new segment selector
/// and return value on the stack and use lretl
/// to reload cs and continue at 1:.
pub unsafe fn set_cs(sel: SegmentSelector) {
    asm!("pushl $0; \
          pushl $$1f; \
          lretl; \
          1:" :: "ri" (sel.bits() as usize) : "memory");
}

impl SegmentDescriptor {
    pub fn new_memory(base: u32, limit: u32, ty: Type, accessed: bool, dpl: PrivilegeLevel) -> SegmentDescriptor {
        let ty1 = descriptor::Type::SegmentDescriptor {
            ty: ty,
            accessed: accessed,
        };
        let flags = FLAGS_DB;
        let seg = SegmentDescriptor::memory_or_tss(base, limit, ty1, dpl, flags);
        seg
    }

    pub fn new_tss(tss: &TaskStateSegment, dpl: PrivilegeLevel) -> [SegmentDescriptor; 2] {
        let tss_ptr = tss as *const TaskStateSegment;
        let ty1 = descriptor::Type::SystemDescriptor {
            size: true,
            ty: descriptor::SystemType::TssAvailable,
        };
        let seg = SegmentDescriptor::memory_or_tss(tss_ptr as u32, size_of::<TaskStateSegment>() as u32, ty1, dpl, Flags::empty());
        seg
    }
}
<commit_msg>Fix return value for 32-bit version of new_tss.<commit_after>use core::mem::size_of;

use bits32::task::*;
use shared::descriptor;
use shared::PrivilegeLevel;
pub use shared::segmentation::*;

/// Reload code segment register.
/// Note this is special since we can not directly move
/// to %cs. Instead we push the new segment selector
/// and return value on the stack and use lretl
/// to reload cs and continue at 1:.
pub unsafe fn set_cs(sel: SegmentSelector) {
    asm!("pushl $0; \
          pushl $$1f; \
          lretl; \
          1:" :: "ri" (sel.bits() as usize) : "memory");
}

impl SegmentDescriptor {
    pub fn new_memory(base: u32, limit: u32, ty: Type, accessed: bool, dpl: PrivilegeLevel) -> SegmentDescriptor {
        let ty1 = descriptor::Type::SegmentDescriptor {
            ty: ty,
            accessed: accessed,
        };
        let flags = FLAGS_DB;
        let seg = SegmentDescriptor::memory_or_tss(base, limit, ty1, dpl, flags);
        seg
    }

    pub fn new_tss(tss: &TaskStateSegment, dpl: PrivilegeLevel) -> SegmentDescriptor {
        let tss_ptr = tss as *const TaskStateSegment;
        let ty1 = descriptor::Type::SystemDescriptor {
            size: true,
            ty: descriptor::SystemType::TssAvailable,
        };
        let seg = SegmentDescriptor::memory_or_tss(tss_ptr as u32, size_of::<TaskStateSegment>() as u32, ty1, dpl, Flags::empty());
        seg
    }
}
<|endoftext|>