<commit_before>use events::publish;
use eyre::Result;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::path::Path;
use strum::{Display, EnumString, EnumVariantNames};
use tracing::Event;
use validator::Validate;

/// Logging level
#[derive(
    Debug,
    Display,
    Clone,
    Copy,
    PartialEq,
    PartialOrd,
    JsonSchema,
    Deserialize,
    Serialize,
    EnumString,
    EnumVariantNames,
)]
#[serde(rename_all = "lowercase")]
#[strum(serialize_all = "lowercase")]
pub enum LoggingLevel {
    Trace,
    Debug,
    Info,
    Warn,
    Error,
    Never,
}

/// Create a `LoggingLevel` from a `tracing::Level`
impl From<&tracing::Level> for LoggingLevel {
    fn from(level: &tracing::Level) -> Self {
        match *level {
            tracing::Level::TRACE => Self::Trace,
            tracing::Level::DEBUG => Self::Debug,
            tracing::Level::INFO => Self::Info,
            tracing::Level::WARN => Self::Warn,
            tracing::Level::ERROR => Self::Error,
        }
    }
}

/// Logging format
#[derive(
    Debug, PartialEq, Clone, Copy, JsonSchema, Deserialize, Serialize, EnumString, EnumVariantNames,
)]
#[serde(rename_all = "lowercase")]
#[strum(serialize_all = "lowercase")]
pub enum LoggingFormat {
    Simple,
    Detail,
    Json,
}

pub mod config {
    use super::*;
    use defaults::Defaults;
    use std::fs;
    use std::{env, path::PathBuf};

    /// Get the directory where logs are stored
    pub fn dir(ensure: bool) -> Result<PathBuf> {
        let config = crate::config::dir(false)?;
        let dir = match env::consts::OS {
            "macos" | "windows" => config.join("Logs"),
            _ => config.join("logs"),
        };
        if ensure {
            fs::create_dir_all(&dir)?;
        }
        Ok(dir)
    }

    /// Logging to standard error stream
    ///
    /// Configuration settings for log entries printed to stderr when using the CLI
    #[derive(
        Debug, Defaults, PartialEq, Clone, Copy, JsonSchema, Deserialize, Serialize, Validate,
    )]
    #[serde(default)]
    #[schemars(deny_unknown_fields)]
    pub struct LoggingStdErrConfig {
        /// The maximum log level to emit
        #[def = "LoggingLevel::Info"]
        pub level: LoggingLevel,

        /// The format for the logs entries
        #[def = "LoggingFormat::Simple"]
        pub format: LoggingFormat,
    }

    /// Logging to desktop notifications
    ///
    /// Configuration settings for log entries shown to the user in the desktop
    #[derive(
        Debug, Defaults, PartialEq, Clone, Copy, JsonSchema, Deserialize, Serialize, Validate,
    )]
    #[serde(default)]
    #[schemars(deny_unknown_fields)]
    pub struct LoggingDesktopConfig {
        /// The maximum log level to emit
        #[def = "LoggingLevel::Info"]
        pub level: LoggingLevel,
    }

    /// Logging to file
    ///
    /// Configuration settings for logs entries written to file
    #[derive(Debug, Defaults, PartialEq, Clone, JsonSchema, Deserialize, Serialize, Validate)]
    #[serde(default)]
    #[schemars(deny_unknown_fields)]
    pub struct LoggingFileConfig {
        /// The path of the log file
        #[def = "default_file_path()"]
        pub path: String,

        /// The maximum log level to emit
        #[def = "LoggingLevel::Info"]
        pub level: LoggingLevel,
    }

    /// Get the default value for `logging.file.path`
    pub fn default_file_path() -> String {
        dir(true)
            .expect("Unable to get logs directory")
            .join("log.json")
            .into_os_string()
            .into_string()
            .expect("Unable to convert path to string")
    }

    /// Logging
    ///
    /// Configuration settings for logging
    #[derive(Debug, Default, PartialEq, Clone, JsonSchema, Deserialize, Serialize, Validate)]
    #[serde(default)]
    #[schemars(deny_unknown_fields)]
    pub struct LoggingConfig {
        pub stderr: LoggingStdErrConfig,
        pub desktop: LoggingDesktopConfig,
        pub file: LoggingFileConfig,
    }
}

/// Create a preliminary logging subscriber.
///
/// This can be necessary to ensure that any log events that get emitted during
/// initialization are displayed to the user.
pub fn prelim() -> tracing::subscriber::DefaultGuard {
    let subscriber = tracing_subscriber::fmt()
        .pretty()
        .with_max_level(tracing::Level::INFO)
        .with_writer(std::io::stderr)
        .finish();
    tracing::subscriber::set_default(subscriber)
}

/// Custom tracing_subscriber layer that prints events to stderr filtered
/// by level for the "plain" format. Other formats are handled by `tracing_subscriber`
/// formatters (see below).
struct StderrPlainLayer {
    level: LoggingLevel,
}

#[derive(Default)]
struct StderrVisitor {
    message: String,
}

impl tracing::field::Visit for StderrVisitor {
    fn record_debug(&mut self, field: &tracing::field::Field, value: &dyn std::fmt::Debug) {
        if field.name() == "message" {
            self.message = format!("{:?}", value);
        }
    }
}

impl<S: tracing::subscriber::Subscriber> tracing_subscriber::layer::Layer<S> for StderrPlainLayer {
    fn on_event(&self, event: &Event<'_>, _ctx: tracing_subscriber::layer::Context<'_, S>) {
        let level = LoggingLevel::from(event.metadata().level());
        if level >= self.level {
            let level_name = level.to_string().to_uppercase();

            #[cfg(feature = "cli-pretty")]
            let level_name = {
                use cli_utils::ansi_term::Color::{Blue, Green, Purple, Red, White, Yellow};
                match level {
                    LoggingLevel::Trace => Purple,
                    LoggingLevel::Debug => Blue,
                    LoggingLevel::Info => Green,
                    LoggingLevel::Warn => Yellow,
                    LoggingLevel::Error => Red,
                    _ => White,
                }
                .bold()
                .paint(format!("{:5}", level_name))
            };

            let mut visitor = StderrVisitor::default();
            event.record(&mut visitor);
            eprintln!("{} {}", level_name, visitor.message)
        }
    }
}

/// Custom tracing_subscriber layer that publishes events
/// under the pubsub "logging" topic as a JSON value.
struct PubSubLayer {
    level: LoggingLevel,
}

impl<S: tracing::subscriber::Subscriber> tracing_subscriber::layer::Layer<S> for PubSubLayer {
    fn on_event(&self, event: &Event<'_>, _ctx: tracing_subscriber::layer::Context<'_, S>) {
        use tracing_serde::AsSerde;
        if LoggingLevel::from(event.metadata().level()) >= self.level {
            publish("logging", &event.as_serde())
        }
    }
}

/// Initialize logging
///
/// This initializes a logging subscriber based on configuration and
/// context (e.g. stderr should not be written to if the context
/// is the desktop application).
///
/// # Arguments
///
/// - `stderr`: should stderr logging be enabled
/// - `pubsub`: should pubsub logging be enabled (for desktop notifications)
/// - `file`: should file logging be enabled
/// - `config`: the logging configuration
pub fn init(
    stderr: bool,
    pubsub: bool,
    file: bool,
    config: &config::LoggingConfig,
) -> Result<tracing_appender::non_blocking::WorkerGuard> {
    use tracing_error::ErrorLayer;
    use tracing_subscriber::prelude::*;
    use tracing_subscriber::{fmt, layer::SubscriberExt, EnvFilter};

    // Stderr logging layer
    let stderr_level = if stderr {
        config.stderr.level
    } else {
        LoggingLevel::Never
    };

    // Pubsub logging layer (used for desktop notifications)
    let pubsub_level = if pubsub {
        config.desktop.level
    } else {
        LoggingLevel::Never
    };
    let pubsub_layer = PubSubLayer {
        level: pubsub_level,
    };

    // File logging layer
    let file_level = if file {
        config.file.level
    } else {
        LoggingLevel::Never
    };
    let (file_writer, file_guard) = if file_level != LoggingLevel::Never {
        let path = Path::new(&config.file.path);
        let file_appender =
            tracing_appender::rolling::daily(&path.parent().unwrap(), &path.file_name().unwrap());
        tracing_appender::non_blocking(file_appender)
    } else {
        tracing_appender::non_blocking(std::io::sink())
    };
    let file_layer = fmt::Layer::new().json().with_writer(file_writer);

    // Error reporting layer (necessary for using `eyre` crate)
    let error_layer = ErrorLayer::default();

    // tracing_subscriber does not currently allow for different layers to have different
    // levels so work out the minimum level and filter by that in the root subscriber.
    let mut min_level = LoggingLevel::Never;
    if stderr_level < min_level {
        min_level = stderr_level
    }
    if pubsub_level < min_level {
        min_level = pubsub_level
    }
    if file_level < min_level {
        min_level = file_level
    }

    // Filter out debug log entries from some crates to avoid excessive noise.
    // We may want to show entries from other crates during development
    // so we may add another flag for this in the future.
    // e.g. `--log-scope=stencila` vs `--log-scope=all`.
    let directives = format!(
        "{},html5ever=info,hyper=info,mio=info,reqwest=info,rustyline=info,tokio_tungstenite=info,tungstenite=info,warp=info",
        min_level.to_string()
    );

    let registry = tracing_subscriber::registry()
        .with(EnvFilter::new(directives))
        .with(pubsub_layer)
        .with(file_layer)
        .with(error_layer);

    if config.stderr.format == LoggingFormat::Detail {
        registry.with(fmt::Layer::new().pretty()).init();
    } else if config.stderr.format == LoggingFormat::Json {
        registry.with(fmt::Layer::new().json()).init();
    } else {
        registry
            .with(StderrPlainLayer {
                level: stderr_level,
            })
            .init();
    }

    Ok(file_guard)
}

/// Generate some test tracing events.
///
/// Can be used for testing that events are propagated
/// to subscribers as expected.
#[tracing::instrument]
pub fn test_events() {
    tracing::trace!("A trace event");
    tracing::debug!("A debug event");
    tracing::info!("An info event");
    tracing::warn!("A warn event");
    tracing::error!("An error event");
}

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

    #[test]
    #[allow(clippy::eq_op)]
    fn test_logging_level_ordering() -> Result<()> {
        assert!(LoggingLevel::Debug > LoggingLevel::Trace);
        assert!(LoggingLevel::Debug >= LoggingLevel::Debug);
        assert!(LoggingLevel::Debug == LoggingLevel::Debug);
        assert!(LoggingLevel::Trace <= LoggingLevel::Debug);
        assert!(LoggingLevel::Trace < LoggingLevel::Debug);

        assert!(LoggingLevel::Info > LoggingLevel::Debug);
        assert!(LoggingLevel::Warn > LoggingLevel::Info);
        assert!(LoggingLevel::Error > LoggingLevel::Warn);
        Ok(())
    }
}
<commit_msg>chore(Logging): Ignore trace and debug logs from external packages<commit_after>use events::publish;
use eyre::Result;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::path::Path;
use strum::{Display, EnumString, EnumVariantNames};
use tracing::Event;
use validator::Validate;

/// Logging level
#[derive(
    Debug,
    Display,
    Clone,
    Copy,
    PartialEq,
    PartialOrd,
    JsonSchema,
    Deserialize,
    Serialize,
    EnumString,
    EnumVariantNames,
)]
#[serde(rename_all = "lowercase")]
#[strum(serialize_all = "lowercase")]
pub enum LoggingLevel {
    Trace,
    Debug,
    Info,
    Warn,
    Error,
    Never,
}

/// Create a `LoggingLevel` from a `tracing::Level`
impl From<&tracing::Level> for LoggingLevel {
    fn from(level: &tracing::Level) -> Self {
        match *level {
            tracing::Level::TRACE => Self::Trace,
            tracing::Level::DEBUG => Self::Debug,
            tracing::Level::INFO => Self::Info,
            tracing::Level::WARN => Self::Warn,
            tracing::Level::ERROR => Self::Error,
        }
    }
}

/// Logging format
#[derive(
    Debug, PartialEq, Clone, Copy, JsonSchema, Deserialize, Serialize, EnumString, EnumVariantNames,
)]
#[serde(rename_all = "lowercase")]
#[strum(serialize_all = "lowercase")]
pub enum LoggingFormat {
    Simple,
    Detail,
    Json,
}

pub mod config {
    use super::*;
    use defaults::Defaults;
    use std::fs;
    use std::{env, path::PathBuf};

    /// Get the directory where logs are stored
    pub fn dir(ensure: bool) -> Result<PathBuf> {
        let config = crate::config::dir(false)?;
        let dir = match env::consts::OS {
            "macos" | "windows" => config.join("Logs"),
            _ => config.join("logs"),
        };
        if ensure {
            fs::create_dir_all(&dir)?;
        }
        Ok(dir)
    }

    /// Logging to standard error stream
    ///
    /// Configuration settings for log entries printed to stderr when using the CLI
    #[derive(
        Debug, Defaults, PartialEq, Clone, Copy, JsonSchema, Deserialize, Serialize, Validate,
    )]
    #[serde(default)]
    #[schemars(deny_unknown_fields)]
    pub struct LoggingStdErrConfig {
        /// The maximum log level to emit
        #[def = "LoggingLevel::Info"]
        pub level: LoggingLevel,

        /// The format for the logs entries
        #[def = "LoggingFormat::Simple"]
        pub format: LoggingFormat,
    }

    /// Logging to desktop notifications
    ///
    /// Configuration settings for log entries shown to the user in the desktop
    #[derive(
        Debug, Defaults, PartialEq, Clone, Copy, JsonSchema, Deserialize, Serialize, Validate,
    )]
    #[serde(default)]
    #[schemars(deny_unknown_fields)]
    pub struct LoggingDesktopConfig {
        /// The maximum log level to emit
        #[def = "LoggingLevel::Info"]
        pub level: LoggingLevel,
    }

    /// Logging to file
    ///
    /// Configuration settings for logs entries written to file
    #[derive(Debug, Defaults, PartialEq, Clone, JsonSchema, Deserialize, Serialize, Validate)]
    #[serde(default)]
    #[schemars(deny_unknown_fields)]
    pub struct LoggingFileConfig {
        /// The path of the log file
        #[def = "default_file_path()"]
        pub path: String,

        /// The maximum log level to emit
        #[def = "LoggingLevel::Info"]
        pub level: LoggingLevel,
    }

    /// Get the default value for `logging.file.path`
    pub fn default_file_path() -> String {
        dir(true)
            .expect("Unable to get logs directory")
            .join("log.json")
            .into_os_string()
            .into_string()
            .expect("Unable to convert path to string")
    }

    /// Logging
    ///
    /// Configuration settings for logging
    #[derive(Debug, Default, PartialEq, Clone, JsonSchema, Deserialize, Serialize, Validate)]
    #[serde(default)]
    #[schemars(deny_unknown_fields)]
    pub struct LoggingConfig {
        pub stderr: LoggingStdErrConfig,
        pub desktop: LoggingDesktopConfig,
        pub file: LoggingFileConfig,
    }
}

/// Create a preliminary logging subscriber.
///
/// This can be necessary to ensure that any log events that get emitted during
/// initialization are displayed to the user.
pub fn prelim() -> tracing::subscriber::DefaultGuard {
    let subscriber = tracing_subscriber::fmt()
        .pretty()
        .with_max_level(tracing::Level::INFO)
        .with_writer(std::io::stderr)
        .finish();
    tracing::subscriber::set_default(subscriber)
}

/// Custom tracing_subscriber layer that prints events to stderr filtered
/// by level for the "plain" format. Other formats are handled by `tracing_subscriber`
/// formatters (see below).
struct StderrPlainLayer {
    level: LoggingLevel,
}

#[derive(Default)]
struct StderrVisitor {
    message: String,
}

impl tracing::field::Visit for StderrVisitor {
    fn record_debug(&mut self, field: &tracing::field::Field, value: &dyn std::fmt::Debug) {
        if field.name() == "message" {
            self.message = format!("{:?}", value);
        }
    }
}

impl<S: tracing::subscriber::Subscriber> tracing_subscriber::layer::Layer<S> for StderrPlainLayer {
    fn on_event(&self, event: &Event<'_>, _ctx: tracing_subscriber::layer::Context<'_, S>) {
        let level = LoggingLevel::from(event.metadata().level());
        if level >= self.level {
            let level_name = level.to_string().to_uppercase();

            #[cfg(feature = "cli-pretty")]
            let level_name = {
                use cli_utils::ansi_term::Color::{Blue, Green, Purple, Red, White, Yellow};
                match level {
                    LoggingLevel::Trace => Purple,
                    LoggingLevel::Debug => Blue,
                    LoggingLevel::Info => Green,
                    LoggingLevel::Warn => Yellow,
                    LoggingLevel::Error => Red,
                    _ => White,
                }
                .bold()
                .paint(format!("{:5}", level_name))
            };

            let mut visitor = StderrVisitor::default();
            event.record(&mut visitor);
            eprintln!("{} {}", level_name, visitor.message)
        }
    }
}

/// Custom tracing_subscriber layer that publishes events
/// under the pubsub "logging" topic as a JSON value.
struct PubSubLayer {
    level: LoggingLevel,
}

impl<S: tracing::subscriber::Subscriber> tracing_subscriber::layer::Layer<S> for PubSubLayer {
    fn on_event(&self, event: &Event<'_>, _ctx: tracing_subscriber::layer::Context<'_, S>) {
        use tracing_serde::AsSerde;
        if LoggingLevel::from(event.metadata().level()) >= self.level {
            publish("logging", &event.as_serde())
        }
    }
}

/// Initialize logging
///
/// This initializes a logging subscriber based on configuration and
/// context (e.g. stderr should not be written to if the context
/// is the desktop application).
///
/// # Arguments
///
/// - `stderr`: should stderr logging be enabled
/// - `pubsub`: should pubsub logging be enabled (for desktop notifications)
/// - `file`: should file logging be enabled
/// - `config`: the logging configuration
pub fn init(
    stderr: bool,
    pubsub: bool,
    file: bool,
    config: &config::LoggingConfig,
) -> Result<tracing_appender::non_blocking::WorkerGuard> {
    use tracing_error::ErrorLayer;
    use tracing_subscriber::prelude::*;
    use tracing_subscriber::{fmt, layer::SubscriberExt, EnvFilter};

    // Stderr logging layer
    let stderr_level = if stderr {
        config.stderr.level
    } else {
        LoggingLevel::Never
    };

    // Pubsub logging layer (used for desktop notifications)
    let pubsub_level = if pubsub {
        config.desktop.level
    } else {
        LoggingLevel::Never
    };
    let pubsub_layer = PubSubLayer {
        level: pubsub_level,
    };

    // File logging layer
    let file_level = if file {
        config.file.level
    } else {
        LoggingLevel::Never
    };
    let (file_writer, file_guard) = if file_level != LoggingLevel::Never {
        let path = Path::new(&config.file.path);
        let file_appender =
            tracing_appender::rolling::daily(&path.parent().unwrap(), &path.file_name().unwrap());
        tracing_appender::non_blocking(file_appender)
    } else {
        tracing_appender::non_blocking(std::io::sink())
    };
    let file_layer = fmt::Layer::new().json().with_writer(file_writer);

    // Error reporting layer (necessary for using `eyre` crate)
    let error_layer = ErrorLayer::default();

    // tracing_subscriber does not currently allow for different layers to have different
    // levels so work out the minimum level and filter by that in the root subscriber.
    let mut min_level = LoggingLevel::Never;
    if stderr_level < min_level {
        min_level = stderr_level
    }
    if pubsub_level < min_level {
        min_level = pubsub_level
    }
    if file_level < min_level {
        min_level = file_level
    }

    // Filter out debug log entries from some crates to avoid excessive noise.
    // We may want to show entries from other crates during development
    // so we may add another flag for this in the future.
    // e.g. `--log-scope=stencila` vs `--log-scope=all`.
    let directives = format!(
        "{},async_io=info,html5ever=info,hyper=info,mio=info,polling=info,reqwest=info,rustyline=info,tokio_tungstenite=info,tungstenite=info,warp=info",
        min_level.to_string()
    );

    let registry = tracing_subscriber::registry()
        .with(EnvFilter::new(directives))
        .with(pubsub_layer)
        .with(file_layer)
        .with(error_layer);

    if config.stderr.format == LoggingFormat::Detail {
        registry.with(fmt::Layer::new().pretty()).init();
    } else if config.stderr.format == LoggingFormat::Json {
        registry.with(fmt::Layer::new().json()).init();
    } else {
        registry
            .with(StderrPlainLayer {
                level: stderr_level,
            })
            .init();
    }

    Ok(file_guard)
}

/// Generate some test tracing events.
///
/// Can be used for testing that events are propagated
/// to subscribers as expected.
#[tracing::instrument]
pub fn test_events() {
    tracing::trace!("A trace event");
    tracing::debug!("A debug event");
    tracing::info!("An info event");
    tracing::warn!("A warn event");
    tracing::error!("An error event");
}

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

    #[test]
    #[allow(clippy::eq_op)]
    fn test_logging_level_ordering() -> Result<()> {
        assert!(LoggingLevel::Debug > LoggingLevel::Trace);
        assert!(LoggingLevel::Debug >= LoggingLevel::Debug);
        assert!(LoggingLevel::Debug == LoggingLevel::Debug);
        assert!(LoggingLevel::Trace <= LoggingLevel::Debug);
        assert!(LoggingLevel::Trace < LoggingLevel::Debug);

        assert!(LoggingLevel::Info > LoggingLevel::Debug);
        assert!(LoggingLevel::Warn > LoggingLevel::Info);
        assert!(LoggingLevel::Error > LoggingLevel::Warn);
        Ok(())
    }
}
<|endoftext|>


<commit_before>use neat::*;

#[derive(Debug, Clone)]
pub struct Organism {
    pub genome: Genome,
    pub fitness: f64,
    pub neurons: Vec<Option<Neuron>>
}

const ACTIVATION_CYCLES: usize = 10;

impl Organism {
    pub fn new(genome: Genome) -> Organism {
        Organism { genome: genome, fitness: 0f64, neurons: vec![] }
    }

    pub fn mutate(&self) -> Organism {
        let mut new_genome = self.genome.clone();
        new_genome.mutate();
        Organism::new(new_genome)
    }

    pub fn mate(&self, other: &Organism) -> Organism {
        Organism::new(self.genome.mate(&other.genome, self.fitness < other.fitness))
    }

    pub fn activate_old(&mut self, sensors: &Vec<f64>, outputs: &mut Vec<f64>){
       if self.neurons.len() == 0 {
           self.generate_phenome();
       };

       for _n in 0..ACTIVATION_CYCLES {
           for neuron_id in 0..sensors.len() {
               if neuron_id < self.neurons.len() {
                   self.neurons[neuron_id].as_mut().unwrap().stimulate(sensors[neuron_id]);
               }
           }

           self.activate_neurons();
           self.propagate_signals();
       }

       //Take outputs from next neurons after sensors
       let sensors_len = sensors.len();
       for neuron_id in sensors_len..(sensors_len + outputs.len()){
           if neuron_id < self.neurons.len() {
               outputs[neuron_id - sensors_len] = self.neurons[neuron_id].as_ref().map_or(0f64, |neuron| neuron.potential());
           } else {
               outputs[neuron_id - sensors_len] = 0f64;
           }
       }

       for neuron in &mut self.neurons {
           if neuron.is_some() {
               neuron.as_mut().unwrap().relax();
           }
       }
    }

    pub fn activate(&mut self, sensors: &Vec<f64>, outputs: &mut Vec<f64>){

        let neurons_len = self.genome.len();
        let gamma = vec![0.0; neurons_len];
        let tau = vec![10.0; neurons_len];
        let theta = vec![0.0; neurons_len];
        let wik = vec![1.0; sensors.len() * neurons_len];
        let i = sensors.clone();
        let activations = Ctrnn::new().activate(30, &gamma, 1.0, &tau, &self.get_weights_matrix(), &theta, &(neurons_len, sensors.len(), wik), &i);
        if sensors.len() < neurons_len {
            let outputs_activations = activations.split_at(sensors.len()).1.to_vec();
            for n in 0..outputs_activations.len() {
                outputs[n] = outputs_activations[n];
            }
        }
    }

    fn activate_neurons(&mut self){
        for neuron_id in 0..self.neurons.len() {
            self.neurons[neuron_id].as_mut().unwrap().shot();
        }
    }

    fn propagate_signals(&mut self){
        for neuron_option in self.neurons.clone() {
            let neuron = neuron_option.unwrap();
            for connection in &neuron.connections {
               self.neurons[connection.0].as_mut().unwrap().stimulate(neuron.potential() * connection.1);
            }
        }
    }

    fn generate_phenome(&mut self){
        let neurons_to_generate = self.genome.len();

        self.neurons = vec![Some(Neuron::new()); neurons_to_generate as usize];

        for gene in self.genome.get_genes() {
            let mut neuron = self.neurons[gene.in_neuron_id].as_mut().unwrap();
            neuron.connections.push(Connection(gene.out_neuron_id, gene.weight));
        }
    }

    fn get_weights_matrix(&self) -> (usize, usize, Vec<f64>){
        let neurons_len = self.genome.len();
        let mut matrix = vec![0.0; neurons_len * neurons_len];
        for gene in self.genome.get_genes() {
            if gene.enabled {
                matrix[(gene.out_neuron_id * neurons_len) + gene.in_neuron_id] = gene.weight
            }
        }
        (neurons_len, neurons_len, matrix)
    }
}

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

    #[test]
    fn should_be_able_to_generate_his_phenome(){
        let mut organism = Organism::new(Genome::new());
        organism.genome.inject_gene(0, 0, 0.1f64);
        organism.genome.inject_gene(0, 1, 0.2f64);
        organism.genome.inject_gene(1, 0, 0.3f64);
        organism.genome.inject_gene(1, 1, 0.4f64);
        organism.generate_phenome();
        assert!(organism.neurons.len() == 2);
        let neuron0 = &organism.neurons[0].as_ref().unwrap();
        let connection00 = &neuron0.connections[0];
        assert!(connection00.0 == 0usize);
        assert!(connection00.1 == 0.1f64);
        let connection01 = &neuron0.connections[1];
        assert!(connection01.0 == 1usize);
        assert!(connection01.1 == 0.2f64);
        let neuron1 = &organism.neurons[1].as_ref().unwrap();
        let connection10 = &neuron1.connections[0];
        assert!(connection10.0 == 0usize);
        assert!(connection10.1 == 0.3f64);
        let connection11 = &neuron1.connections[1];
        assert!(connection11.0 == 1usize);
        assert!(connection11.1 == 0.4f64);
    }

    #[test]
    fn should_propagate_signal_without_hidden_layers(){
        let mut organism = Organism::new(Genome::new());
        organism.genome.inject_gene(0, 1, 2f64);
        let sensors = vec![1f64];
        let mut output = vec![0f64];
        organism.activate(&sensors, &mut output);
        assert!(output[0] > 0f64, format!("{:?} is not bigger than 0.9", output[0]));

        let mut organism = Organism::new(Genome::new());
        organism.genome.inject_gene(0, 1, -2f64);
        let sensors = vec![1f64];
        let mut output = vec![0f64];
        organism.activate(&sensors, &mut output);
        assert!(output[0] < 0.1f64, format!("{:?} is not smaller than 0.1", output[0]));
    }

    #[test]
    fn should_propagate_signal_over_hidden_layers(){
        let mut organism = Organism::new(Genome::new());
        organism.genome.inject_gene(0, 1, 0f64); //disable connection
        organism.genome.inject_gene(0, 2, 1f64);
        organism.genome.inject_gene(2, 1, 1f64);
        let sensors = vec![0f64];
        let mut output = vec![0f64];
        organism.activate(&sensors, &mut output);
        assert!(output[0] > 0.9f64, format!("{:?} is not bigger than 0.9", output[0]));
    }

    #[test]
    fn should_work_with_cyclic_networks(){
        let mut organism = Organism::new(Genome::new());
        organism.genome.inject_gene(0, 1, 1f64);
        organism.genome.inject_gene(1, 2, 1f64);
        organism.genome.inject_gene(2, 1, 1f64);
        let mut output = vec![0f64];
        organism.activate(&vec![1f64], &mut output);
        assert!(output[0] > 0.9, format!("{:?} is not bigger than 0.9", output[0]));

        let mut organism = Organism::new(Genome::new());
        organism.genome.inject_gene(0, 1, -1f64);
        organism.genome.inject_gene(1, 2, -1f64);
        organism.genome.inject_gene(2, 1, -1f64);
        let mut output = vec![0f64];
        organism.activate(&vec![1f64], &mut output);
        assert!(output[0] < 0.1, format!("{:?} is not smaller than 0.1", output[0]));
    }

    #[test]
    fn activate_organims_sensor_without_enough_neurons_should_ignore_it(){
        let mut organism = Organism::new(Genome::new());
        organism.genome.inject_gene(0, 1, 1f64);
        let sensors = vec![0f64,0f64,0f64];
        let mut output = vec![0f64];
        organism.activate(&sensors, &mut output);
    }

    #[test]
    fn should_be_able_to_get_matrix_representation_of_the_neuron_connections(){
        let mut organism = Organism::new(Genome::new());
        organism.genome.inject_gene(0, 1, 1f64);
        organism.genome.inject_gene(1, 2, 0.5f64);
        organism.genome.inject_gene(2, 1, 0.5f64);
        organism.genome.inject_gene(2, 2, 0.75f64);
        organism.genome.inject_gene(1, 0, 1f64);
        assert_eq!(
            organism.get_weights_matrix(),
                (3, 3, vec![
                        0.0, 1.0, 0.0,
                        1.0, 0.0, 0.5,
                        0.0, 0.5, 0.75
                    ])
        );
    }
}
<commit_msg>Fix output neurons update after activation<commit_after>use neat::*;

#[derive(Debug, Clone)]
pub struct Organism {
    pub genome: Genome,
    pub fitness: f64,
    pub neurons: Vec<Option<Neuron>>
}

const ACTIVATION_CYCLES: usize = 10;

impl Organism {
    pub fn new(genome: Genome) -> Organism {
        Organism { genome: genome, fitness: 0f64, neurons: vec![] }
    }

    pub fn mutate(&self) -> Organism {
        let mut new_genome = self.genome.clone();
        new_genome.mutate();
        Organism::new(new_genome)
    }

    pub fn mate(&self, other: &Organism) -> Organism {
        Organism::new(self.genome.mate(&other.genome, self.fitness < other.fitness))
    }

    pub fn activate_old(&mut self, sensors: &Vec<f64>, outputs: &mut Vec<f64>){
       if self.neurons.len() == 0 {
           self.generate_phenome();
       };

       for _n in 0..ACTIVATION_CYCLES {
           for neuron_id in 0..sensors.len() {
               if neuron_id < self.neurons.len() {
                   self.neurons[neuron_id].as_mut().unwrap().stimulate(sensors[neuron_id]);
               }
           }

           self.activate_neurons();
           self.propagate_signals();
       }

       //Take outputs from next neurons after sensors
       let sensors_len = sensors.len();
       for neuron_id in sensors_len..(sensors_len + outputs.len()){
           if neuron_id < self.neurons.len() {
               outputs[neuron_id - sensors_len] = self.neurons[neuron_id].as_ref().map_or(0f64, |neuron| neuron.potential());
           } else {
               outputs[neuron_id - sensors_len] = 0f64;
           }
       }

       for neuron in &mut self.neurons {
           if neuron.is_some() {
               neuron.as_mut().unwrap().relax();
           }
       }
    }

    pub fn activate(&mut self, sensors: &Vec<f64>, outputs: &mut Vec<f64>){

        let neurons_len = self.genome.len();
        let gamma = vec![0.0; neurons_len];
        let tau = vec![10.0; neurons_len];
        let theta = vec![0.0; neurons_len];
        let wik = vec![1.0; sensors.len() * neurons_len];
        let i = sensors.clone();
        let activations = Ctrnn::new().activate(30, &gamma, 1.0, &tau, &self.get_weights_matrix(), &theta, &(neurons_len, sensors.len(), wik), &i);
        if sensors.len() < neurons_len {
            let outputs_activations = activations.split_at(sensors.len()).1.to_vec();
            for n in 0..outputs.len() {
                outputs[n] = outputs_activations[n];
            }
        }
    }

    fn activate_neurons(&mut self){
        for neuron_id in 0..self.neurons.len() {
            self.neurons[neuron_id].as_mut().unwrap().shot();
        }
    }

    fn propagate_signals(&mut self){
        for neuron_option in self.neurons.clone() {
            let neuron = neuron_option.unwrap();
            for connection in &neuron.connections {
               self.neurons[connection.0].as_mut().unwrap().stimulate(neuron.potential() * connection.1);
            }
        }
    }

    fn generate_phenome(&mut self){
        let neurons_to_generate = self.genome.len();

        self.neurons = vec![Some(Neuron::new()); neurons_to_generate as usize];

        for gene in self.genome.get_genes() {
            let mut neuron = self.neurons[gene.in_neuron_id].as_mut().unwrap();
            neuron.connections.push(Connection(gene.out_neuron_id, gene.weight));
        }
    }

    fn get_weights_matrix(&self) -> (usize, usize, Vec<f64>){
        let neurons_len = self.genome.len();
        let mut matrix = vec![0.0; neurons_len * neurons_len];
        for gene in self.genome.get_genes() {
            if gene.enabled {
                matrix[(gene.out_neuron_id * neurons_len) + gene.in_neuron_id] = gene.weight
            }
        }
        (neurons_len, neurons_len, matrix)
    }
}

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

    #[test]
    fn should_be_able_to_generate_his_phenome(){
        let mut organism = Organism::new(Genome::new());
        organism.genome.inject_gene(0, 0, 0.1f64);
        organism.genome.inject_gene(0, 1, 0.2f64);
        organism.genome.inject_gene(1, 0, 0.3f64);
        organism.genome.inject_gene(1, 1, 0.4f64);
        organism.generate_phenome();
        assert!(organism.neurons.len() == 2);
        let neuron0 = &organism.neurons[0].as_ref().unwrap();
        let connection00 = &neuron0.connections[0];
        assert!(connection00.0 == 0usize);
        assert!(connection00.1 == 0.1f64);
        let connection01 = &neuron0.connections[1];
        assert!(connection01.0 == 1usize);
        assert!(connection01.1 == 0.2f64);
        let neuron1 = &organism.neurons[1].as_ref().unwrap();
        let connection10 = &neuron1.connections[0];
        assert!(connection10.0 == 0usize);
        assert!(connection10.1 == 0.3f64);
        let connection11 = &neuron1.connections[1];
        assert!(connection11.0 == 1usize);
        assert!(connection11.1 == 0.4f64);
    }

    #[test]
    fn should_propagate_signal_without_hidden_layers(){
        let mut organism = Organism::new(Genome::new());
        organism.genome.inject_gene(0, 1, 2f64);
        let sensors = vec![1f64];
        let mut output = vec![0f64];
        organism.activate(&sensors, &mut output);
        assert!(output[0] > 0.9f64, format!("{:?} is not bigger than 0.9", output[0]));

        let mut organism = Organism::new(Genome::new());
        organism.genome.inject_gene(0, 1, -2f64);
        let sensors = vec![1f64];
        let mut output = vec![0f64];
        organism.activate(&sensors, &mut output);
        assert!(output[0] < 0.1f64, format!("{:?} is not smaller than 0.1", output[0]));
    }

    #[test]
    fn should_propagate_signal_over_hidden_layers(){
        let mut organism = Organism::new(Genome::new());
        organism.genome.inject_gene(0, 1, 0f64);
        organism.genome.inject_gene(0, 2, 2f64);
        organism.genome.inject_gene(2, 1, 2f64);
        let sensors = vec![0f64];
        let mut output = vec![0f64];
        organism.activate(&sensors, &mut output);
        assert!(output[0] > 0.9f64, format!("{:?} is not bigger than 0.9", output[0]));
    }

    #[test]
    fn should_work_with_cyclic_networks(){
        let mut organism = Organism::new(Genome::new());
        organism.genome.inject_gene(0, 1, 2f64);
        organism.genome.inject_gene(1, 2, 2f64);
        organism.genome.inject_gene(2, 1, 2f64);
        let mut output = vec![0f64];
        organism.activate(&vec![1f64], &mut output);
        assert!(output[0] > 0.9, format!("{:?} is not bigger than 0.9", output[0]));

        let mut organism = Organism::new(Genome::new());
        organism.genome.inject_gene(0, 1, -2f64);
        organism.genome.inject_gene(1, 2, -2f64);
        organism.genome.inject_gene(2, 1, -2f64);
        let mut output = vec![0f64];
        organism.activate(&vec![1f64], &mut output);
        assert!(output[0] < 0.1, format!("{:?} is not smaller than 0.1", output[0]));
    }

    #[test]
    fn activate_organims_sensor_without_enough_neurons_should_ignore_it(){
        let mut organism = Organism::new(Genome::new());
        organism.genome.inject_gene(0, 1, 1f64);
        let sensors = vec![0f64,0f64,0f64];
        let mut output = vec![0f64];
        organism.activate(&sensors, &mut output);
    }

    #[test]
    fn should_be_able_to_get_matrix_representation_of_the_neuron_connections(){
        let mut organism = Organism::new(Genome::new());
        organism.genome.inject_gene(0, 1, 1f64);
        organism.genome.inject_gene(1, 2, 0.5f64);
        organism.genome.inject_gene(2, 1, 0.5f64);
        organism.genome.inject_gene(2, 2, 0.75f64);
        organism.genome.inject_gene(1, 0, 1f64);
        assert_eq!(
            organism.get_weights_matrix(),
                (3, 3, vec![
                        0.0, 1.0, 0.0,
                        1.0, 0.0, 0.5,
                        0.0, 0.5, 0.75
                    ])
        );
    }
}
<|endoftext|>


<commit_before>extern mod opengles;   // FIXME: Should only be for tests.
use glut::{check_loop, create_window, destroy_window, init, init_display_mode, swap_buffers};
use opengles::gl2::{ARRAY_BUFFER, COLOR_BUFFER_BIT, COMPILE_STATUS};
use opengles::gl2::{FRAGMENT_SHADER, LINK_STATUS, NO_ERROR, STATIC_DRAW};
use opengles::gl2::{TRIANGLE_STRIP, VERTEX_SHADER, GLclampf, GLenum};
use opengles::gl2::{GLsizei, GLuint, attach_shader, bind_buffer};
use opengles::gl2::{buffer_data, create_program, clear, clear_color};
use opengles::gl2::{compile_shader, create_shader, draw_arrays};
use opengles::gl2::{enable_vertex_attrib_array, gen_buffers};
use opengles::gl2::{get_attrib_location, get_error, get_program_iv};
use opengles::gl2::{get_shader_info_log, get_shader_iv};
use opengles::gl2::{get_uniform_location, link_program, shader_source};
use opengles::gl2::{use_program, vertex_attrib_pointer_f32};

use comm::{Chan, peek, Port, recv, send};
use io::println;
use ptr::{addr_of, null};
use str::to_bytes;
use task::TaskBuilder;
use vec::raw::to_ptr;

fn fragment_shader_source() -> ~str {
    ~"
    #ifdef GLES2
        precision mediump float;
    #endif

        void main(void) {
            gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
        }
    "
}

fn vertex_shader_source() -> ~str {
    ~"
        attribute vec3 aVertexPosition;

        /*uniform mat4 uMVMatrix;
        uniform mat4 uPMatrix;*/

        void main(void) {
            gl_Position = /*uPMatrix * uMVMatrix **/
                vec4(aVertexPosition, 1.0);
        }
    "
}

fn load_shader(source_str: ~str, shader_type: GLenum) -> GLuint {
    let shader_id = create_shader(shader_type);
    shader_source(shader_id, ~[to_bytes(source_str)]);
    compile_shader(shader_id);

    if get_error() != NO_ERROR {
        println(fmt!("error: %d", get_error() as int));
        fail ~"failed to compile shader with error";
    }

    if get_shader_iv(shader_id, COMPILE_STATUS) == (0 as GLint) {
        println(get_shader_info_log(shader_id));
        fail ~"failed to compile shader";
    }
    return shader_id;
}

struct ShaderProgram {
    program: GLuint,
    aVertexPosition: c_int,
    /*let uPMatrix: c_int;
    let uMVMatrix: c_int;*/
}

fn ShaderProgram(program: GLuint) -> ShaderProgram {
    let p = ShaderProgram {
        program : program,
        aVertexPosition : get_attrib_location(program, ~"aVertexPosition"),
        /*self.uPMatrix : get_uniform_location(program, "uPMatrix"),
        self.uMVMatrix : get_uniform_location(program, "uMVMatrix")*/
    };
    enable_vertex_attrib_array(p.aVertexPosition as GLuint);
    return p;
}

fn init_shaders() -> ShaderProgram {
    let vertex_shader = load_shader(vertex_shader_source(), VERTEX_SHADER);
    let fragment_shader = load_shader(fragment_shader_source(),
                                      FRAGMENT_SHADER);

    let program = create_program();
    attach_shader(program, vertex_shader);
    attach_shader(program, fragment_shader);
    link_program(program);

    if get_program_iv(program, LINK_STATUS) == (0 as GLint) {
        fail ~"failed to initialize program";
    }

    use_program(program);

    return ShaderProgram(program);
}

fn init_buffers() -> GLuint {
    let triangle_vertex_buffer = gen_buffers(1 as GLsizei)[0];
    bind_buffer(ARRAY_BUFFER, triangle_vertex_buffer);
    let vertices = ~[
        0.0f32, 1.0f32, 0.0f32,
        1.0f32, 0.0f32, 0.0f32,
        0.0f32, 0.0f32, 0.0f32
    ];
    buffer_data(ARRAY_BUFFER, vertices, STATIC_DRAW);
    return triangle_vertex_buffer;
}

fn draw_scene(shader_program: ShaderProgram, vertex_buffer: GLuint) {
    clear_color(0.0f32, 0.0f32, 1.0f32, 1.0f32);
    clear(COLOR_BUFFER_BIT);

    bind_buffer(ARRAY_BUFFER, vertex_buffer);
    vertex_attrib_pointer_f32(shader_program.aVertexPosition as GLuint,
                              3 as GLint, false, 0 as GLsizei, 0 as GLuint);
    draw_arrays(TRIANGLE_STRIP, 0 as GLint, 3 as GLint);
}

fn display_callback() {
    let program = init_shaders();
    let vertex_buffer = init_buffers();
    draw_scene(program, vertex_buffer);

    swap_buffers();
}

#[test]
fn test_triangle_and_square() unsafe {
    let builder = task::task().sched_mode(task::PlatformThread);

    let po: Port<()> = Port();
    let ch = Chan(&po);
    let _result_ch: Chan<()> = builder.spawn_listener(|_port| {
        init();
        init_display_mode(0 as c_uint);
        let window = create_window(~"Rust GLUT");
        display_func(display_callback);

        let wakeup: Port<()> = Port();
        let wakeup_chan = Chan(&wakeup);
        timer_func(1000, || send(wakeup_chan, ()));

        loop {
            check_loop();

            if peek(wakeup) {
                recv(wakeup);
                send(ch, ());
                destroy_window(window);
                break;
            }
        }
    });

    recv(po);
}

<commit_msg>Fix tests<commit_after>extern mod opengles;   // FIXME: Should only be for tests.
use glut::{check_loop, create_window, destroy_window, init, init_display_mode, swap_buffers, GLint};
use self::opengles::gl2::{ARRAY_BUFFER, COLOR_BUFFER_BIT, COMPILE_STATUS};
use self::opengles::gl2::{FRAGMENT_SHADER, LINK_STATUS, NO_ERROR, STATIC_DRAW};
use self::opengles::gl2::{TRIANGLE_STRIP, VERTEX_SHADER, GLclampf, GLenum};
use self::opengles::gl2::{GLsizei, GLuint, attach_shader, bind_buffer};
use self::opengles::gl2::{buffer_data, create_program, clear, clear_color};
use self::opengles::gl2::{compile_shader, create_shader, draw_arrays};
use self::opengles::gl2::{enable_vertex_attrib_array, gen_buffers};
use self::opengles::gl2::{get_attrib_location, get_error, get_program_iv};
use self::opengles::gl2::{get_shader_info_log, get_shader_iv};
use self::opengles::gl2::{get_uniform_location, link_program, shader_source};
use self::opengles::gl2::{use_program, vertex_attrib_pointer_f32};

use libc::{c_int, c_uint};
use oldcomm::{Chan, peek, Port, recv, send};
use io::println;
use ptr::{addr_of, null};
use str::to_bytes;
use task::TaskBuilder;
use vec::raw::to_ptr;

fn fragment_shader_source() -> ~str {
    ~"
    #ifdef GLES2
        precision mediump float;
    #endif

        void main(void) {
            gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
        }
    "
}

fn vertex_shader_source() -> ~str {
    ~"
        attribute vec3 aVertexPosition;

        /*uniform mat4 uMVMatrix;
        uniform mat4 uPMatrix;*/

        void main(void) {
            gl_Position = /*uPMatrix * uMVMatrix **/
                vec4(aVertexPosition, 1.0);
        }
    "
}

fn load_shader(source_str: ~str, shader_type: GLenum) -> GLuint {
    let shader_id = create_shader(shader_type);
    shader_source(shader_id, ~[to_bytes(source_str)]);
    compile_shader(shader_id);

    if get_error() != NO_ERROR {
        println(fmt!("error: %d", get_error() as int));
        fail ~"failed to compile shader with error";
    }

    if get_shader_iv(shader_id, COMPILE_STATUS) == (0 as GLint) {
        println(get_shader_info_log(shader_id));
        fail ~"failed to compile shader";
    }
    return shader_id;
}

struct ShaderProgram {
    program: GLuint,
    aVertexPosition: c_int,
    /*let uPMatrix: c_int;
    let uMVMatrix: c_int;*/
}

fn ShaderProgram(program: GLuint) -> ShaderProgram {
    let p = ShaderProgram {
        program : program,
        aVertexPosition : get_attrib_location(program, ~"aVertexPosition"),
        /*self.uPMatrix : get_uniform_location(program, "uPMatrix"),
        self.uMVMatrix : get_uniform_location(program, "uMVMatrix")*/
    };
    enable_vertex_attrib_array(p.aVertexPosition as GLuint);
    return p;
}

fn init_shaders() -> ShaderProgram {
    let vertex_shader = load_shader(vertex_shader_source(), VERTEX_SHADER);
    let fragment_shader = load_shader(fragment_shader_source(),
                                      FRAGMENT_SHADER);

    let program = create_program();
    attach_shader(program, vertex_shader);
    attach_shader(program, fragment_shader);
    link_program(program);

    if get_program_iv(program, LINK_STATUS) == (0 as GLint) {
        fail ~"failed to initialize program";
    }

    use_program(program);

    return ShaderProgram(program);
}

fn init_buffers() -> GLuint {
    let triangle_vertex_buffer = gen_buffers(1 as GLsizei)[0];
    bind_buffer(ARRAY_BUFFER, triangle_vertex_buffer);
    let vertices = ~[
        0.0f32, 1.0f32, 0.0f32,
        1.0f32, 0.0f32, 0.0f32,
        0.0f32, 0.0f32, 0.0f32
    ];
    buffer_data(ARRAY_BUFFER, vertices, STATIC_DRAW);
    return triangle_vertex_buffer;
}

fn draw_scene(shader_program: ShaderProgram, vertex_buffer: GLuint) {
    clear_color(0.0f32, 0.0f32, 1.0f32, 1.0f32);
    clear(COLOR_BUFFER_BIT);

    bind_buffer(ARRAY_BUFFER, vertex_buffer);
    vertex_attrib_pointer_f32(shader_program.aVertexPosition as GLuint,
                              3 as GLint, false, 0 as GLsizei, 0 as GLuint);
    draw_arrays(TRIANGLE_STRIP, 0 as GLint, 3 as GLint);
}

fn display_callback() {
    let program = init_shaders();
    let vertex_buffer = init_buffers();
    draw_scene(program, vertex_buffer);

    swap_buffers();
}

/*
#[test]
fn test_triangle_and_square() unsafe {
    let builder = task::task().sched_mode(task::PlatformThread);

    let po: Port<()> = Port();
    let ch = Chan(&po);
    let _result_ch: Chan<()> = builder.spawn_listener(|_port| {
        init();
        init_display_mode(0 as c_uint);
        let window = create_window(~"Rust GLUT");
        display_func(display_callback);

        let wakeup: Port<()> = Port();
        let wakeup_chan = Chan(&wakeup);
        timer_func(1000, || send(wakeup_chan, ()));

        loop {
            check_loop();

            if peek(wakeup) {
                recv(wakeup);
                send(ch, ());
                destroy_window(window);
                break;
            }
        }
    });

    recv(po);
}

*/<|endoftext|>


<commit_before>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

extern mod opengles;   // FIXME: Should only be for tests.
use glut::{swap_buffers, GLint};
use glut::{init, DOUBLE, init_display_mode, create_window, display_func, timer_func, check_loop, destroy_window};
use self::opengles::gl2::{ARRAY_BUFFER, COLOR_BUFFER_BIT, COMPILE_STATUS};
use self::opengles::gl2::{FRAGMENT_SHADER, LINK_STATUS, NO_ERROR, STATIC_DRAW};
use self::opengles::gl2::{TRIANGLE_STRIP, VERTEX_SHADER, GLenum};
use self::opengles::gl2::{GLsizei, GLuint, attach_shader, bind_buffer};
use self::opengles::gl2::{buffer_data, create_program, clear, clear_color};
use self::opengles::gl2::{compile_shader, create_shader, draw_arrays};
use self::opengles::gl2::{enable_vertex_attrib_array, gen_buffers};
use self::opengles::gl2::{get_attrib_location, get_error, get_program_iv};
use self::opengles::gl2::{get_shader_info_log, get_shader_iv};
use self::opengles::gl2::{link_program, shader_source};
use self::opengles::gl2::{use_program, vertex_attrib_pointer_f32};

use std::comm;
use std::libc::c_int;
use std::io::println;
use std::task;

fn fragment_shader_source() -> ~str {
    ~"
    #ifdef GLES2
        precision mediump float;
    #endif

        void main(void) {
            gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
        }
    "
}

fn vertex_shader_source() -> ~str {
    ~"
        attribute vec3 aVertexPosition;

        /*uniform mat4 uMVMatrix;
        uniform mat4 uPMatrix;*/

        void main(void) {
            gl_Position = /*uPMatrix * uMVMatrix **/
                vec4(aVertexPosition, 1.0);
        }
    "
}

fn load_shader(source_str: ~str, shader_type: GLenum) -> GLuint {
    let shader_id = create_shader(shader_type);
    shader_source(shader_id, ~[source_str.as_bytes().to_owned()]);
    compile_shader(shader_id);

    if get_error() != NO_ERROR {
        println(fmt!("error: %d", get_error() as int));
        fail!(~"failed to compile shader with error");
    }

    if get_shader_iv(shader_id, COMPILE_STATUS) == (0 as GLint) {
        println(get_shader_info_log(shader_id));
        fail!(~"failed to compile shader");
    }
    return shader_id;
}

struct ShaderProgram {
    program: GLuint,
    aVertexPosition: c_int,
    /*let uPMatrix: c_int;
    let uMVMatrix: c_int;*/
}

fn ShaderProgram(program: GLuint) -> ShaderProgram {
    let p = ShaderProgram {
        program : program,
        aVertexPosition : get_attrib_location(program, ~"aVertexPosition"),
        /*self.uPMatrix : get_uniform_location(program, "uPMatrix"),
        self.uMVMatrix : get_uniform_location(program, "uMVMatrix")*/
    };
    enable_vertex_attrib_array(p.aVertexPosition as GLuint);
    return p;
}

fn init_shaders() -> ShaderProgram {
    let vertex_shader = load_shader(vertex_shader_source(), VERTEX_SHADER);
    let fragment_shader = load_shader(fragment_shader_source(),
                                      FRAGMENT_SHADER);

    let program = create_program();
    attach_shader(program, vertex_shader);
    attach_shader(program, fragment_shader);
    link_program(program);

    if get_program_iv(program, LINK_STATUS) == (0 as GLint) {
        fail!(~"failed to initialize program");
    }

    use_program(program);

    return ShaderProgram(program);
}

fn init_buffers() -> GLuint {
    let triangle_vertex_buffer = gen_buffers(1 as GLsizei)[0];
    bind_buffer(ARRAY_BUFFER, triangle_vertex_buffer);
    let vertices = ~[
        0.0f32, 1.0f32, 0.0f32,
        1.0f32, 0.0f32, 0.0f32,
        0.0f32, 0.0f32, 0.0f32
    ];
    buffer_data(ARRAY_BUFFER, vertices, STATIC_DRAW);
    return triangle_vertex_buffer;
}

fn draw_scene(shader_program: ShaderProgram, vertex_buffer: GLuint) {
    clear_color(0.0f32, 0.0f32, 1.0f32, 1.0f32);
    clear(COLOR_BUFFER_BIT);

    bind_buffer(ARRAY_BUFFER, vertex_buffer);
    vertex_attrib_pointer_f32(shader_program.aVertexPosition as GLuint,
                              3 as GLint, false, 0 as GLsizei, 0 as GLuint);
    draw_arrays(TRIANGLE_STRIP, 0 as GLint, 3 as GLint);
}

fn display_callback() {
    let program = init_shaders();
    let vertex_buffer = init_buffers();
    draw_scene(program, vertex_buffer);

    swap_buffers();
}

/*
#[test]
fn test_triangle_and_square() {
    let (po, ch): (Port<()>, Chan<()>) = stream();
    let _result_ch: Chan<()> = do spawn_listener | _po | {
        init();
        init_display_mode(DOUBLE);
        let window = create_window(~"Rust GLUT");
        display_func(display_callback);

        let (wakeup, wakeup_chan): (Port<()>, Chan<()>) = stream();

        do timer_func(1000) { wakeup_chan.send(()); }

        loop {
            check_loop();

            if wakeup.peek() {
                wakeup.recv();
                ch.send(());
                destroy_window(window);
                break;
            }
        }
    };

    po.recv();
}
*/

pub fn spawn_listener<A: Send>(f: ~fn(Port<A>)) -> Chan<A> {
    let (setup_po, setup_ch) = comm::stream();
    do task::spawn {
        let (po, ch) = comm::stream();
        setup_ch.send(ch);
        f(po);
    }
    setup_po.recv()
}
<commit_msg>Fix test warnings with new Rust.<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

extern mod opengles;   // FIXME: Should only be for tests.
use glut::{swap_buffers, GLint};
use self::opengles::gl2::{ARRAY_BUFFER, COLOR_BUFFER_BIT, COMPILE_STATUS};
use self::opengles::gl2::{FRAGMENT_SHADER, LINK_STATUS, NO_ERROR, STATIC_DRAW};
use self::opengles::gl2::{TRIANGLE_STRIP, VERTEX_SHADER, GLenum};
use self::opengles::gl2::{GLsizei, GLuint, attach_shader, bind_buffer};
use self::opengles::gl2::{buffer_data, create_program, clear, clear_color};
use self::opengles::gl2::{compile_shader, create_shader, draw_arrays};
use self::opengles::gl2::{enable_vertex_attrib_array, gen_buffers};
use self::opengles::gl2::{get_attrib_location, get_error, get_program_iv};
use self::opengles::gl2::{get_shader_info_log, get_shader_iv};
use self::opengles::gl2::{link_program, shader_source};
use self::opengles::gl2::{use_program, vertex_attrib_pointer_f32};

use std::comm;
use std::libc::c_int;
use std::io::println;
use std::task;

fn fragment_shader_source() -> ~str {
    ~"
    #ifdef GLES2
        precision mediump float;
    #endif

        void main(void) {
            gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
        }
    "
}

fn vertex_shader_source() -> ~str {
    ~"
        attribute vec3 aVertexPosition;

        /*uniform mat4 uMVMatrix;
        uniform mat4 uPMatrix;*/

        void main(void) {
            gl_Position = /*uPMatrix * uMVMatrix **/
                vec4(aVertexPosition, 1.0);
        }
    "
}

fn load_shader(source_str: ~str, shader_type: GLenum) -> GLuint {
    let shader_id = create_shader(shader_type);
    shader_source(shader_id, [source_str.as_bytes().to_owned()]);
    compile_shader(shader_id);

    if get_error() != NO_ERROR {
        println(fmt!("error: %d", get_error() as int));
        fail!(~"failed to compile shader with error");
    }

    if get_shader_iv(shader_id, COMPILE_STATUS) == (0 as GLint) {
        println(get_shader_info_log(shader_id));
        fail!(~"failed to compile shader");
    }
    return shader_id;
}

struct ShaderProgram {
    program: GLuint,
    aVertexPosition: c_int,
    /*let uPMatrix: c_int;
    let uMVMatrix: c_int;*/
}

fn ShaderProgram(program: GLuint) -> ShaderProgram {
    let p = ShaderProgram {
        program : program,
        aVertexPosition : get_attrib_location(program, ~"aVertexPosition"),
        /*self.uPMatrix : get_uniform_location(program, "uPMatrix"),
        self.uMVMatrix : get_uniform_location(program, "uMVMatrix")*/
    };
    enable_vertex_attrib_array(p.aVertexPosition as GLuint);
    return p;
}

fn init_shaders() -> ShaderProgram {
    let vertex_shader = load_shader(vertex_shader_source(), VERTEX_SHADER);
    let fragment_shader = load_shader(fragment_shader_source(),
                                      FRAGMENT_SHADER);

    let program = create_program();
    attach_shader(program, vertex_shader);
    attach_shader(program, fragment_shader);
    link_program(program);

    if get_program_iv(program, LINK_STATUS) == (0 as GLint) {
        fail!(~"failed to initialize program");
    }

    use_program(program);

    return ShaderProgram(program);
}

fn init_buffers() -> GLuint {
    let triangle_vertex_buffer = gen_buffers(1 as GLsizei)[0];
    bind_buffer(ARRAY_BUFFER, triangle_vertex_buffer);
    let vertices = ~[
        0.0f32, 1.0f32, 0.0f32,
        1.0f32, 0.0f32, 0.0f32,
        0.0f32, 0.0f32, 0.0f32
    ];
    buffer_data(ARRAY_BUFFER, vertices, STATIC_DRAW);
    return triangle_vertex_buffer;
}

fn draw_scene(shader_program: ShaderProgram, vertex_buffer: GLuint) {
    clear_color(0.0f32, 0.0f32, 1.0f32, 1.0f32);
    clear(COLOR_BUFFER_BIT);

    bind_buffer(ARRAY_BUFFER, vertex_buffer);
    vertex_attrib_pointer_f32(shader_program.aVertexPosition as GLuint,
                              3 as GLint, false, 0 as GLsizei, 0 as GLuint);
    draw_arrays(TRIANGLE_STRIP, 0 as GLint, 3 as GLint);
}

fn display_callback() {
    let program = init_shaders();
    let vertex_buffer = init_buffers();
    draw_scene(program, vertex_buffer);

    swap_buffers();
}

/*
#[test]
fn test_triangle_and_square() {
    let (po, ch): (Port<()>, Chan<()>) = stream();
    let _result_ch: Chan<()> = do spawn_listener | _po | {
        init();
        init_display_mode(DOUBLE);
        let window = create_window(~"Rust GLUT");
        display_func(display_callback);

        let (wakeup, wakeup_chan): (Port<()>, Chan<()>) = stream();

        do timer_func(1000) { wakeup_chan.send(()); }

        loop {
            check_loop();

            if wakeup.peek() {
                wakeup.recv();
                ch.send(());
                destroy_window(window);
                break;
            }
        }
    };

    po.recv();
}
*/

pub fn spawn_listener<A: Send>(f: ~fn(Port<A>)) -> Chan<A> {
    let (setup_po, setup_ch) = comm::stream();
    do task::spawn {
        let (po, ch) = comm::stream();
        setup_ch.send(ch);
        f(po);
    }
    setup_po.recv()
}
<|endoftext|>


<commit_before>// FIXME: Needs additional cocoa setup on OS X. rust-cocoa should probably just
// be a dependency
use sdl::*;
use start;

#[test]
pub fn test_everything() {
    do start::start {
        start_tests();
    }
}

fn start_tests() {
    assert init(~[InitVideo, InitTimer]) == true;
    run_tests(~[
        general::test_was_init,
        // FIXME: Busted, segfault
        //general::test_set_error,
        //general::test_error,
        //general::test_clear_error,
        test_video::test_set_video_mode,
        // FIXME: Doesn't work when called from a directory that
        // doesn't contain the test image file
        //test_video::test_blit,
        test_event::test_poll_event_none,
        // FIXME: This test is interactive
        //test_event::test_keyboard,

    ]);

    quit();
}

fn run_tests(tests: &[extern fn()]) {
    for tests.each |test| {
        (*test)();
    }
}

mod general {

    use sdl::*;

    pub fn test_was_init() {
        assert vec::contains(~[InitTimer], &InitTimer);
    }

    pub fn test_set_error() {
        set_error(~"test");
        assert get_error() == ~"test";
    }

    pub fn test_error() {
        clear_error();
        assert str::is_empty(get_error());
        error(ENoMem);
        assert str::is_not_empty(get_error());
    }

    pub fn test_clear_error() {
        set_error(~"test");
        clear_error();
        assert str::is_empty(get_error());
    }
}

mod test_event {

    use event;
    use video;
    use keyboard;

    pub fn test_poll_event_none() {
        assert event::poll_event() == event::NoEvent;
    }

    pub fn test_keyboard() {
        io::println(~"press a key in the window");
        let maybe_surface = video::set_video_mode(320, 200, 32,
            ~[video::SWSurface], ~[video::DoubleBuf, video::Resizable]);

        match maybe_surface {
            result::Ok(_) => {
                let mut keydown = false;
                let mut keyup = false;
                while !keydown || !keyup {
                    match event::poll_event() {
                      event::KeyUpEvent(keyboard) => {
                          keyup = true;
                          assert keyboard.keycode != keyboard::SDLKUnknown;
                      },
                      event::KeyDownEvent(keyboard) => {
                          keydown = true;
                          assert keyboard.keycode != keyboard::SDLKUnknown;
                      },
                      event::QuitEvent => fail,
                      _ => { }
                    }
                }
            }
            result::Err(_) => {
                fail;
            }
        }
    }
}

mod test_video {

    pub fn test_set_video_mode() {
        let maybe_surface = ::video::set_video_mode(320, 200, 32,
            ~[::video::HWSurface], ~[::video::DoubleBuf]);

        assert result::is_ok(&maybe_surface);
    }

    pub fn test_blit() {
        let maybe_screen = ::video::set_video_mode(320, 200, 32,
            ~[::video::SWSurface], ~[::video::DoubleBuf]);

        assert result::is_ok(&maybe_screen);

        match maybe_screen {
            result::Ok(screen) => {
                // FIXME: We need to load this from the crate instead of
                // off the filesystem
                let maybe_image = match ::video::load_bmp(~"rust-logo-128x128-blk.bmp") {
                    result::Ok(raw_image) => {
                        raw_image.display_format()
                    },
                    result::Err(err) => result::Err(err)
                };

                assert result::is_ok(&maybe_image);

                match maybe_image {
                    result::Ok(image) => {
                        for iter::repeat(1u) || {
                            screen.blit_surface(image);
                            screen.flip();
                            ::event::poll_event();
                        };
                    },
                    result::Err(_) => ()
                };
            },
            result::Err(_) => ()
        };
    }
}
<commit_msg>Corrected tests to no longer use nonexistent str::is_not_empty<commit_after>// FIXME: Needs additional cocoa setup on OS X. rust-cocoa should probably just
// be a dependency
use sdl::*;
use start;

#[test]
pub fn test_everything() {
    do start::start {
        start_tests();
    }
}

fn start_tests() {
    assert init(~[InitVideo, InitTimer]) == true;
    run_tests(~[
        general::test_was_init,
        // FIXME: Busted, segfault
        //general::test_set_error,
        //general::test_error,
        //general::test_clear_error,
        test_video::test_set_video_mode,
        // FIXME: Doesn't work when called from a directory that
        // doesn't contain the test image file
        //test_video::test_blit,
        test_event::test_poll_event_none,
        // FIXME: This test is interactive
        //test_event::test_keyboard,

    ]);

    quit();
}

fn run_tests(tests: &[extern fn()]) {
    for tests.each |test| {
        (*test)();
    }
}

mod general {

    use sdl::*;

    pub fn test_was_init() {
        assert vec::contains(~[InitTimer], &InitTimer);
    }

    pub fn test_set_error() {
        set_error(~"test");
        assert get_error() == ~"test";
    }

    pub fn test_error() {
        clear_error();
        assert str::is_empty(get_error());
        error(ENoMem);
        assert (str::is_empty(get_error()) == false);
    }

    pub fn test_clear_error() {
        set_error(~"test");
        clear_error();
        assert str::is_empty(get_error());
    }
}

mod test_event {

    use event;
    use video;
    use keyboard;

    pub fn test_poll_event_none() {
        assert event::poll_event() == event::NoEvent;
    }

    pub fn test_keyboard() {
        io::println(~"press a key in the window");
        let maybe_surface = video::set_video_mode(320, 200, 32,
            ~[video::SWSurface], ~[video::DoubleBuf, video::Resizable]);

        match maybe_surface {
            result::Ok(_) => {
                let mut keydown = false;
                let mut keyup = false;
                while !keydown || !keyup {
                    match event::poll_event() {
                      event::KeyUpEvent(keyboard) => {
                          keyup = true;
                          assert keyboard.keycode != keyboard::SDLKUnknown;
                      },
                      event::KeyDownEvent(keyboard) => {
                          keydown = true;
                          assert keyboard.keycode != keyboard::SDLKUnknown;
                      },
                      event::QuitEvent => fail,
                      _ => { }
                    }
                }
            }
            result::Err(_) => {
                fail;
            }
        }
    }
}

mod test_video {

    pub fn test_set_video_mode() {
        let maybe_surface = ::video::set_video_mode(320, 200, 32,
            ~[::video::HWSurface], ~[::video::DoubleBuf]);

        assert result::is_ok(&maybe_surface);
    }

    pub fn test_blit() {
        let maybe_screen = ::video::set_video_mode(320, 200, 32,
            ~[::video::SWSurface], ~[::video::DoubleBuf]);

        assert result::is_ok(&maybe_screen);

        match maybe_screen {
            result::Ok(screen) => {
                // FIXME: We need to load this from the crate instead of
                // off the filesystem
                let maybe_image = match ::video::load_bmp(~"rust-logo-128x128-blk.bmp") {
                    result::Ok(raw_image) => {
                        raw_image.display_format()
                    },
                    result::Err(err) => result::Err(err)
                };

                assert result::is_ok(&maybe_image);

                match maybe_image {
                    result::Ok(image) => {
                        for iter::repeat(1u) || {
                            screen.blit_surface(image);
                            screen.flip();
                            ::event::poll_event();
                        };
                    },
                    result::Err(_) => ()
                };
            },
            result::Err(_) => ()
        };
    }
}
<|endoftext|>


<commit_before>export uuid;
export uuid_random;
export uuid_time;
export to_str;
export from_str;

#[doc = "a uuid value"]
type uuid = {
    a: u32,
    b: u32,
    c: u32,
    d: u32,
};

#[cfg(target_os = "macos")]
#[nolink]
native mod uuid {
    fn uuid_generate(out: uuid);
    fn uuid_generate_random(out: uuid);
    fn uuid_generate_time(out: uuid);

    fn uuid_parse(s: *u8, uuid: uuid) -> libc::c_int;

    fn uuid_unparse(uuid: uuid, out: *u8);
    fn uuid_unparse_lower(uuid: uuid, out: *u8);
    fn uuid_unparse_upper(uuid: uuid, out: *u8);
}

#[cfg(target_os = "linux")]
#[cfg(target_os = "freebsd")]
native mod uuid {
    fn uuid_generate(out: uuid);
    fn uuid_generate_random(out: uuid);
    fn uuid_generate_time(out: uuid);

    fn uuid_parse(s: *u8, uuid: uuid) -> libc::c_int;

    fn uuid_unparse(uuid: uuid, out: *u8);
    fn uuid_unparse_lower(uuid: uuid, out: *u8);
    fn uuid_unparse_upper(uuid: uuid, out: *u8);
}

#[doc = "Create a new uuid"]
fn uuid() -> uuid {
    let uuid = { a: 0u32, b: 0u32, c: 0u32, d: 0u32 };
    uuid::uuid_generate(uuid);
    uuid
}

#[doc = "Create a uuid from the current time and mac address"]
fn uuid_random() -> uuid {
    let uuid = { a: 0u32, b: 0u32, c: 0u32, d: 0u32 };
    uuid::uuid_generate_random(uuid);
    uuid
}

#[doc = "Create a uuid from a random number generator"]
fn uuid_time() -> uuid {
    let uuid = { a: 0u32, b: 0u32, c: 0u32, d: 0u32 };
    uuid::uuid_generate_time(uuid);
    uuid
}

#[doc = "Convert a uuid to a string"]
fn to_str(uuid: uuid) -> str {
    let mut s = "";
    str::reserve(s, 36u);
    unsafe { str::unsafe::set_len(s, 36u); }
    str::as_buf(s) { |buf|
        uuid::uuid_unparse(uuid, buf);
    }
    s
}

#[doc = "Convert a string to a uuid"]
fn from_str(s: str) -> uuid {
    assert str::len(s) == 36u;

    let uuid = { a: 0u32, b: 0u32, c: 0u32, d: 0u32 };
    str::as_buf(s) { |buf|
        uuid::uuid_parse(buf, uuid);
    }
    uuid
}

#[cfg(test)]
mod test {
    #[test]
    fn test() {
        uint::range(0u, 100000u) { |_i|
            let uuid = uuid();
            assert uuid == from_str(to_str(uuid));

            let uuid = uuid_random();
            assert uuid == from_str(to_str(uuid));

            let uuid = uuid_time();
            assert uuid == from_str(to_str(uuid));
        }
    }
}
<commit_msg>Update for Rust 0.3 changes<commit_after>export uuid;
export uuid_random;
export uuid_time;
export to_str;
export from_str;

#[doc = "a uuid value"]
type uuid = {
    a: u32,
    b: u32,
    c: u32,
    d: u32,
};

#[cfg(target_os = "macos")]
#[nolink]
extern mod uuid {
    fn uuid_generate(out: uuid);
    fn uuid_generate_random(out: uuid);
    fn uuid_generate_time(out: uuid);

    fn uuid_parse(s: *u8, uuid: uuid) -> libc::c_int;

    fn uuid_unparse(uuid: uuid, out: *u8);
    fn uuid_unparse_lower(uuid: uuid, out: *u8);
    fn uuid_unparse_upper(uuid: uuid, out: *u8);
}

#[cfg(target_os = "linux")]
#[cfg(target_os = "freebsd")]
extern mod uuid {
    fn uuid_generate(out: uuid);
    fn uuid_generate_random(out: uuid);
    fn uuid_generate_time(out: uuid);

    fn uuid_parse(s: *u8, uuid: uuid) -> libc::c_int;

    fn uuid_unparse(uuid: uuid, out: *u8);
    fn uuid_unparse_lower(uuid: uuid, out: *u8);
    fn uuid_unparse_upper(uuid: uuid, out: *u8);
}

#[doc = "Create a new uuid"]
fn uuid() -> uuid {
    let uuid = { a: 0u32, b: 0u32, c: 0u32, d: 0u32 };
    uuid::uuid_generate(uuid);
    uuid
}

#[doc = "Create a uuid from the current time and mac address"]
fn uuid_random() -> uuid {
    let uuid = { a: 0u32, b: 0u32, c: 0u32, d: 0u32 };
    uuid::uuid_generate_random(uuid);
    uuid
}

#[doc = "Create a uuid from a random number generator"]
fn uuid_time() -> uuid {
    let uuid = { a: 0u32, b: 0u32, c: 0u32, d: 0u32 };
    uuid::uuid_generate_time(uuid);
    uuid
}

#[doc = "Convert a uuid to a string"]
fn to_str(uuid: uuid) -> str {
    let mut s = "";
    str::reserve(s, 36u);
    unsafe { str::unsafe::set_len(s, 36u); }
    do str::as_buf(s) |buf| {
        uuid::uuid_unparse(uuid, buf);
    }
    s
}

#[doc = "Convert a string to a uuid"]
fn from_str(s: str) -> uuid {
    assert str::len(s) == 36u;

    let uuid = { a: 0u32, b: 0u32, c: 0u32, d: 0u32 };
    do str::as_buf(s) |buf| {
        uuid::uuid_parse(buf, uuid);
    }
    uuid
}

#[cfg(test)]
mod test {
    #[test]
    fn test() {
        for uint::range(0u, 100000u) |_i| {
            let uuid = uuid();
            assert uuid == from_str(to_str(uuid));

            let uuid = uuid_random();
            assert uuid == from_str(to_str(uuid));

            let uuid = uuid_time();
            assert uuid == from_str(to_str(uuid));
        }
    }
}
<|endoftext|>


<commit_before>use std::fs;
use std::fs::File;
use std::io::prelude::*;
use std::path::{Path, PathBuf};

// This module takes an absolute path to a rustc repo and alters the dependencies to point towards
// the respective rustc subcrates instead of using extern crate xyz.
// This allows rust analyzer to analyze rustc internals and show proper information inside clippy
// code. See https://github.com/rust-analyzer/rust-analyzer/issues/3517 and https://github.com/rust-lang/rust-clippy/issues/5514 for details

/// # Panics
///
/// Panics if `rustc_path` does not lead to a rustc repo or the files could not be read
pub fn run(rustc_path: Option<&str>) {
    // we can unwrap here because the arg is required by clap
    let rustc_path = PathBuf::from(rustc_path.unwrap());
    assert!(rustc_path.is_dir(), "path is not a directory");
    let rustc_source_basedir = rustc_path.join("compiler");
    assert!(
        rustc_source_basedir.is_dir(),
        "are you sure the path leads to a rustc repo?"
    );

    let clippy_root_manifest = fs::read_to_string("Cargo.toml").expect("failed to read ./Cargo.toml");
    let clippy_root_lib_rs = fs::read_to_string("src/driver.rs").expect("failed to read ./src/driver.rs");
    inject_deps_into_manifest(
        &rustc_source_basedir,
        "Cargo.toml",
        &clippy_root_manifest,
        &clippy_root_lib_rs,
    )
    .expect("Failed to inject deps into ./Cargo.toml");

    let clippy_lints_manifest =
        fs::read_to_string("clippy_lints/Cargo.toml").expect("failed to read ./clippy_lints/Cargo.toml");
    let clippy_lints_lib_rs =
        fs::read_to_string("clippy_lints/src/lib.rs").expect("failed to read ./clippy_lints/src/lib.rs");
    inject_deps_into_manifest(
        &rustc_source_basedir,
        "clippy_lints/Cargo.toml",
        &clippy_lints_manifest,
        &clippy_lints_lib_rs,
    )
    .expect("Failed to inject deps into ./clippy_lints/Cargo.toml");
}

fn inject_deps_into_manifest(
    rustc_source_dir: &Path,
    manifest_path: &str,
    cargo_toml: &str,
    lib_rs: &str,
) -> std::io::Result<()> {
    // do not inject deps if we have aleady done so
    if cargo_toml.contains("[target.'cfg(NOT_A_PLATFORM)'.dependencies]") {
        eprintln!(
            "cargo dev ra_setup: warning: deps already found inside {}, doing nothing.",
            manifest_path
        );
        return Ok(());
    }

    let extern_crates = lib_rs
        .lines()
        // get the deps
        .filter(|line| line.starts_with("extern crate"))
        // we have something like "extern crate foo;", we only care about the "foo"
        //              ↓          ↓
        // extern crate rustc_middle;
        .map(|s| &s[13..(s.len() - 1)]);

    let new_deps = extern_crates.map(|dep| {
        // format the dependencies that are going to be put inside the Cargo.toml
        format!(
            "{dep} = {{ path = \"{source_path}/{dep}\" }}\n",
            dep = dep,
            source_path = rustc_source_dir.display()
        )
    });

    // format a new [dependencies]-block with the new deps we need to inject
    let mut all_deps = String::from("[target.'cfg(NOT_A_PLATFORM)'.dependencies]\n");
    new_deps.for_each(|dep_line| {
        all_deps.push_str(&dep_line);
    });
    all_deps.push_str("\n[dependencies]\n");

    // replace "[dependencies]" with
    // [dependencies]
    // dep1 = { path = ... }
    // dep2 = { path = ... }
    // etc
    let new_manifest = cargo_toml.replacen("[dependencies]\n", &all_deps, 1);

    // println!("{}", new_manifest);
    let mut file = File::create(manifest_path)?;
    file.write_all(new_manifest.as_bytes())?;

    println!("Dependency paths injected: {}", manifest_path);

    Ok(())
}
<commit_msg>Auto merge of #6679 - flip1995:ra_setup_abs_path, r=Manishearth<commit_after>use std::fs;
use std::fs::File;
use std::io::prelude::*;
use std::path::{Path, PathBuf};

// This module takes an absolute path to a rustc repo and alters the dependencies to point towards
// the respective rustc subcrates instead of using extern crate xyz.
// This allows rust analyzer to analyze rustc internals and show proper information inside clippy
// code. See https://github.com/rust-analyzer/rust-analyzer/issues/3517 and https://github.com/rust-lang/rust-clippy/issues/5514 for details

/// # Panics
///
/// Panics if `rustc_path` does not lead to a rustc repo or the files could not be read
pub fn run(rustc_path: Option<&str>) {
    // we can unwrap here because the arg is required by clap
    let rustc_path = PathBuf::from(rustc_path.unwrap())
        .canonicalize()
        .expect("failed to get the absolute repo path");
    assert!(rustc_path.is_dir(), "path is not a directory");
    let rustc_source_basedir = rustc_path.join("compiler");
    assert!(
        rustc_source_basedir.is_dir(),
        "are you sure the path leads to a rustc repo?"
    );

    let clippy_root_manifest = fs::read_to_string("Cargo.toml").expect("failed to read ./Cargo.toml");
    let clippy_root_lib_rs = fs::read_to_string("src/driver.rs").expect("failed to read ./src/driver.rs");
    inject_deps_into_manifest(
        &rustc_source_basedir,
        "Cargo.toml",
        &clippy_root_manifest,
        &clippy_root_lib_rs,
    )
    .expect("Failed to inject deps into ./Cargo.toml");

    let clippy_lints_manifest =
        fs::read_to_string("clippy_lints/Cargo.toml").expect("failed to read ./clippy_lints/Cargo.toml");
    let clippy_lints_lib_rs =
        fs::read_to_string("clippy_lints/src/lib.rs").expect("failed to read ./clippy_lints/src/lib.rs");
    inject_deps_into_manifest(
        &rustc_source_basedir,
        "clippy_lints/Cargo.toml",
        &clippy_lints_manifest,
        &clippy_lints_lib_rs,
    )
    .expect("Failed to inject deps into ./clippy_lints/Cargo.toml");
}

fn inject_deps_into_manifest(
    rustc_source_dir: &Path,
    manifest_path: &str,
    cargo_toml: &str,
    lib_rs: &str,
) -> std::io::Result<()> {
    // do not inject deps if we have aleady done so
    if cargo_toml.contains("[target.'cfg(NOT_A_PLATFORM)'.dependencies]") {
        eprintln!(
            "cargo dev ra_setup: warning: deps already found inside {}, doing nothing.",
            manifest_path
        );
        return Ok(());
    }

    let extern_crates = lib_rs
        .lines()
        // get the deps
        .filter(|line| line.starts_with("extern crate"))
        // we have something like "extern crate foo;", we only care about the "foo"
        //              ↓          ↓
        // extern crate rustc_middle;
        .map(|s| &s[13..(s.len() - 1)]);

    let new_deps = extern_crates.map(|dep| {
        // format the dependencies that are going to be put inside the Cargo.toml
        format!(
            "{dep} = {{ path = \"{source_path}/{dep}\" }}\n",
            dep = dep,
            source_path = rustc_source_dir.display()
        )
    });

    // format a new [dependencies]-block with the new deps we need to inject
    let mut all_deps = String::from("[target.'cfg(NOT_A_PLATFORM)'.dependencies]\n");
    new_deps.for_each(|dep_line| {
        all_deps.push_str(&dep_line);
    });
    all_deps.push_str("\n[dependencies]\n");

    // replace "[dependencies]" with
    // [dependencies]
    // dep1 = { path = ... }
    // dep2 = { path = ... }
    // etc
    let new_manifest = cargo_toml.replacen("[dependencies]\n", &all_deps, 1);

    // println!("{}", new_manifest);
    let mut file = File::create(manifest_path)?;
    file.write_all(new_manifest.as_bytes())?;

    println!("Dependency paths injected: {}", manifest_path);

    Ok(())
}
<|endoftext|>


<commit_before>use std::sync::Arc;
use mio::*;
use mio::tcp::{TcpStream, TcpSocket};
use mio::buf::ByteBuf;
use std::net::SocketAddr;
use std::net::lookup_host;
use std::collections::VecMap;
use url::Url;
use eventual;

#[derive(Debug, Clone)]
pub enum HttpAction {
    Get(Arc<Url>),
}

pub struct Echo {
    non_block_client: VecMap<TcpStream>,
    action: VecMap<HttpAction>,
    sender: VecMap<eventual::Complete<Box<Vec<u8>>, &'static str>>,
    mut_buf: VecMap<Vec<u8>>,
    buf: Option<ByteBuf>,
    interest: VecMap<Interest>
}

impl Echo {
    pub fn new() -> Echo {
        Echo {
            non_block_client: VecMap::new(),
            action: VecMap::new(),
            sender: VecMap::new(),
            mut_buf: VecMap::new(),
            interest: VecMap::new(),
            buf: None,
        }
    }
}

impl Handler for Echo {
    type Timeout = usize;
    type Message = (String, eventual::Complete<Box<Vec<u8>>, &'static str>);

    fn readable(&mut self, event_loop: &mut EventLoop<Echo>, token: Token, hint: ReadHint) {
        println!("Read");

        let mut buf = ByteBuf::mut_with_capacity(4096 * 16);

        let ref mut non_block_client = match self.non_block_client.get_mut(&token.as_usize()) {
            Some(client) => client,
            None => panic!("Error finding the associated non blocking client {:?}", token)
        };
        let ref mut interest = match self.interest.get_mut(&token.as_usize()) {
            Some(interest) => interest,
            None => panic!("Error finding the associated interest {:?}", token)
        };
        match non_block_client.read(&mut buf) {

            Ok(None) => {
                panic!("We just got readable, but were unable to read from the socket?");
            }
            Ok(Some(r)) => {
                interest.remove(Interest::readable());
                if r == 0 {
                	println!("DONE");
                    event_loop.deregister(*non_block_client).unwrap();
                    let mut_buf = match self.mut_buf.remove(&token.as_usize()) {
                        Some(mut_buf) => mut_buf,
                        None =>
                            panic!("Error finding the mut_buf for {:?} {:?}", token, self.mut_buf)
                    };

                    match self.sender.remove(&token.as_usize()) {
                        Some(completer) => {
                            completer.complete(Box::new(mut_buf));
                            interest.remove(Interest::none());
                        }
                        None => panic!("Error finding the mut_buf for {:?}", token)
                    };

                } else {
        event_loop.reregister(*non_block_client, token, **interest,
                              PollOpt::edge() | PollOpt::oneshot()).unwrap();

                    match self.mut_buf.get_mut(&token.as_usize()) {
                        Some(mut_buf) => mut_buf.push_all(buf.flip().bytes()),
                        None => panic!("Error finding the mut_buf for {:?}", token)
                    }

                    interest.insert(Interest::readable());
                }
            }
            Err(e) => {
                panic!("not implemented; client err={:?}", e);
            }
        }
    }

    fn writable(&mut self, event_loop: &mut EventLoop<Echo>, token: Token) {
        let ref mut action = match self.action.get_mut(&token.as_usize()) {
            Some(action) => action,
            None => panic!("Error finding the associated action {:?}", token)
        };
        let get_command: String = body(action.clone());

        let ref mut non_block_client = match self.non_block_client.get_mut(&token.as_usize()) {
            Some(client) => client,
            None => panic!("Error finding the associated non blocking client {:?}", token)
        };

        let ref mut interest = match self.interest.get_mut(&token.as_usize()) {
            Some(interest) => interest,
            None => panic!("Error finding the associated interest {:?}", token)
        };

        match **action {
            HttpAction::Get(_) => {
                let mut buf = ByteBuf::from_slice(get_command.as_bytes());
                match non_block_client.write(&mut buf) {
                    Ok(None) => {
                        println!("client flushing buf; WOULDBLOCK");
                        self.buf = Some(buf);
                        interest.insert(Interest::writable());
                    }
                    Ok(Some(_)) => {
                        interest.insert(Interest::readable());
                        interest.remove(Interest::writable());
                        event_loop.reregister(*non_block_client, token, **interest,
                                              PollOpt::edge() | PollOpt::oneshot()).unwrap();
                    }
                    Err(e) => panic!("not implemented; client err={:?}", e),
                }
            }
        }
    }
    fn notify(&mut self,
              event_loop: &mut EventLoop<Echo>,
              tuple: (String, eventual::Complete<Box<Vec<u8>>, &'static str>)) {
        let token = Token(self.action.len() + 1);
        let action = get_action(tuple.0);
        self.action.insert(token.as_usize(), action.clone());

        match action {
            HttpAction::Get(url_p) => {
                let url: Url = (*url_p).clone();
                let ip = lookup_host(url.domain().unwrap()).unwrap().next().unwrap().unwrap();
                let port = url.port_or_default().unwrap();
                let address = SocketAddr::new(ip.ip(), port);
                let (sock, _) = TcpSocket::v4().unwrap().connect(&address).unwrap();
                self.non_block_client.insert(token.as_usize(), sock);
                self.sender.insert(token.as_usize(), tuple.1);
                self.mut_buf.insert(token.as_usize(), Vec::new());
                self.interest.insert(token.as_usize(), Interest::hup());
                event_loop.register_opt(self.non_block_client.get(&token.as_usize()).unwrap(),
                                        token, Interest::writable(),
                                        PollOpt::edge() | PollOpt::oneshot()).unwrap();
            }
        }
    }
}

fn body(action: HttpAction) -> String {
    match action {
        HttpAction::Get(ref resource) => {
            format!(
                "GET {}  HTTP/1.1\r\nHost: {}\r\nUser-Agent: curl/7.37.1\r\nAccept */*\r\n\r\n",
                resource.serialize_path().unwrap(), resource.domain().unwrap())
        }
    }
}
fn get_action(url_s: String) -> HttpAction {
    let url = Url::parse(url_s.as_str()).unwrap();
    HttpAction::Get(Arc::new(url))
}<commit_msg>fix build for new version of mio<commit_after>use std::sync::Arc;
use mio::*;
use mio::tcp::{TcpStream, TcpSocket};
use mio::buf::ByteBuf;
use std::net::SocketAddr;
use std::net::lookup_host;
use std::collections::VecMap;
use url::Url;

use eventual;

#[derive(Debug, Clone)]
pub enum HttpAction {
    Get(Arc<Url>),
}

pub struct Echo {
    non_block_client: VecMap<TcpStream>,
    action: VecMap<HttpAction>,
    sender: VecMap<eventual::Complete<Box<Vec<u8>>, &'static str>>,
    mut_buf: VecMap<Vec<u8>>,
    buf: Option<ByteBuf>,
    interest: VecMap<Interest>
}

impl Echo {
    pub fn new() -> Echo {
        Echo {
            non_block_client: VecMap::new(),
            action: VecMap::new(),
            sender: VecMap::new(),
            mut_buf: VecMap::new(),
            interest: VecMap::new(),
            buf: None,
        }
    }
}

impl Handler for Echo {
    type Timeout = usize;
    type Message = (String, eventual::Complete<Box<Vec<u8>>, &'static str>);

    fn readable(&mut self, event_loop: &mut EventLoop<Echo>, token: Token, hint: ReadHint) {
        println!("Read");

        let mut buf = ByteBuf::mut_with_capacity(4096 * 16);

        let ref mut non_block_client = match self.non_block_client.get_mut(&token.as_usize()) {
            Some(client) => client,
            None => panic!("Error finding the associated non blocking client {:?}", token)
        };
        let ref mut interest = match self.interest.get_mut(&token.as_usize()) {
            Some(interest) => interest,
            None => panic!("Error finding the associated interest {:?}", token)
        };
        match non_block_client.try_read_buf(&mut buf) {

            Ok(None) => {
                panic!("We just got readable, but were unable to read from the socket?");
            }
            Ok(Some(r)) => {
                interest.remove(Interest::readable());
                if r == 0 {
                	println!("DONE");
                    event_loop.deregister(*non_block_client).unwrap();
                    let mut_buf = match self.mut_buf.remove(&token.as_usize()) {
                        Some(mut_buf) => mut_buf,
                        None =>
                            panic!("Error finding the mut_buf for {:?} {:?}", token, self.mut_buf)
                    };

                    match self.sender.remove(&token.as_usize()) {
                        Some(completer) => {
                            completer.complete(Box::new(mut_buf));
                            interest.remove(Interest::none());
                        }
                        None => panic!("Error finding the mut_buf for {:?}", token)
                    };

                } else {
        event_loop.reregister(*non_block_client, token, **interest,
                              PollOpt::edge() | PollOpt::oneshot()).unwrap();

                    match self.mut_buf.get_mut(&token.as_usize()) {
                        Some(mut_buf) => mut_buf.push_all(buf.flip().bytes()),
                        None => panic!("Error finding the mut_buf for {:?}", token)
                    }

                    interest.insert(Interest::readable());
                }
            }
            Err(e) => {
                panic!("not implemented; client err={:?}", e);
            }
        }
    }

    fn writable(&mut self, event_loop: &mut EventLoop<Echo>, token: Token) {
        let ref mut action = match self.action.get_mut(&token.as_usize()) {
            Some(action) => action,
            None => panic!("Error finding the associated action {:?}", token)
        };
        let get_command: String = body(action.clone());

        let ref mut non_block_client = match self.non_block_client.get_mut(&token.as_usize()) {
            Some(client) => client,
            None => panic!("Error finding the associated non blocking client {:?}", token)
        };

        let ref mut interest = match self.interest.get_mut(&token.as_usize()) {
            Some(interest) => interest,
            None => panic!("Error finding the associated interest {:?}", token)
        };

        match **action {
            HttpAction::Get(_) => {
                let mut buf = ByteBuf::from_slice(get_command.as_bytes());
                match non_block_client.try_write_buf(&mut buf) {
                    Ok(None) => {
                        println!("client flushing buf; WOULDBLOCK");
                        self.buf = Some(buf);
                        interest.insert(Interest::writable());
                    }
                    Ok(Some(_)) => {
                        interest.insert(Interest::readable());
                        interest.remove(Interest::writable());
                        event_loop.reregister(*non_block_client, token, **interest,
                                              PollOpt::edge() | PollOpt::oneshot()).unwrap();
                    }
                    Err(e) => panic!("not implemented; client err={:?}", e),
                }
            }
        }
    }
    fn notify(&mut self,
              event_loop: &mut EventLoop<Echo>,
              tuple: (String, eventual::Complete<Box<Vec<u8>>, &'static str>)) {
        let token = Token(self.action.len() + 1);
        let action = get_action(tuple.0);
        self.action.insert(token.as_usize(), action.clone());

        match action {
            HttpAction::Get(url_p) => {
                let url: Url = (*url_p).clone();
                let ip = lookup_host(url.domain().unwrap()).unwrap().next().unwrap().unwrap();
                let port = url.port_or_default().unwrap();
                let address = SocketAddr::new(ip.ip(), port);
                let (sock, _) = TcpSocket::v4().unwrap().connect(&address).unwrap();
                self.non_block_client.insert(token.as_usize(), sock);
                self.sender.insert(token.as_usize(), tuple.1);
                self.mut_buf.insert(token.as_usize(), Vec::new());
                self.interest.insert(token.as_usize(), Interest::hup());
                event_loop.register_opt(self.non_block_client.get(&token.as_usize()).unwrap(),
                                        token, Interest::writable(),
                                        PollOpt::edge() | PollOpt::oneshot()).unwrap();
            }
        }
    }
}

fn body(action: HttpAction) -> String {
    match action {
        HttpAction::Get(ref resource) => {
            format!(
                "GET {}  HTTP/1.1\r\nHost: {}\r\nUser-Agent: curl/7.37.1\r\nAccept */*\r\n\r\n",
                resource.serialize_path().unwrap(), resource.domain().unwrap())
        }
    }
}
fn get_action(url_s: String) -> HttpAction {
    let url = Url::parse(url_s.as_str()).unwrap();
    HttpAction::Get(Arc::new(url))
}<|endoftext|>


<commit_before>fn main() {
    let test0 = Vec::new();
    let test1 = vec![2, 1, 2, 1, 0, 1, 2];
    let test2 = vec![1];
    let test3 = vec![7, 1, 5, 3, 6, 4];
    let test4 = vec![2, 4, 1];
}
<commit_msg>finish rust version<commit_after>fn max_profit(prices: Vec<i32>) -> i32 {
    if prices.len() < 1 {
        return 0;
    }

    //let mut max_temp = 0;
    let mut min_temp = prices[0];
    let mut result = 0;

    for i in &prices {
        if *i - min_temp < 0 {
            min_temp = *i
        } else if *i - min_temp > result {
            result = *i - min_temp;
        } else {
            continue;
        }
    }

    if result < 0 {
        0
    } else {
        result
    }
}

fn main() {
    let test0 = Vec::new();
    let test1 = vec![2, 1, 2, 1, 0, 1, 2];
    let test2 = vec![1];
    let test3 = vec![7, 1, 5, 3, 6, 4];
    let test4 = vec![2, 4, 1];

    println!("{}", max_profit(test0));
    println!("{}", max_profit(test1));
    println!("{}", max_profit(test2));
    println!("{}", max_profit(test3));
    println!("{}", max_profit(test4));
}
<|endoftext|>


<commit_before>extern mod std;
extern mod encoding;

use std::net::ip;
use std::net::tcp;
use std::uv_global_loop;

use encoding::{Codec};
use io::{ReaderUtil, WriterUtil};
use tcp::{TcpErrData, TcpNewConnection, TcpSocket};
use task::{SingleThreaded, task};

type KillChan = comm::Chan<Option<TcpErrData>>;
type ContChan = comm::Chan<()>;

fn main() {
    let iotask = uv_global_loop::get();

    let addr = "127.0.0.1";
    let port = 1337;

    let backlog = 128;
    let ip_addr = ip::get_addr(addr, iotask);
    let ip_addr = copy result::unwrap(ip_addr)[0];

    tcp::listen(ip_addr, port, backlog, iotask,
        |kill_ch| on_established(kill_ch),
        |conn, kill_ch| on_new_connection(conn, kill_ch));
}

fn on_established(_kill_ch: KillChan) {
    io::println("running at 127.0.0.1:1337");
}

fn on_new_connection(conn: TcpNewConnection, kill_ch: KillChan) {
    do comm::listen |cont_ch| {
        // Spawn new child which doesn't propagate errors to parent.
        do task().unlinked().sched_mode(SingleThreaded).spawn {
            accept(conn, kill_ch, cont_ch);
        }
        // Wait `tcp::accept(conn)' complete.
        cont_ch.recv();
    }
}

fn accept(conn: TcpNewConnection, kill_ch: KillChan, cont_ch: ContChan) {
    match tcp::accept(conn) {
        Ok(move socket) => {
            cont_ch.send(());
            encode(socket);
        }
        Err(move err_data) => {
            kill_ch.send(Some(err_data));
            cont_ch.send(());
        }
    }
}

fn encode(+socket: TcpSocket) {
    let socket = tcp::socket_buf(socket);

    let mut chunk = ~[];
    let mut buf = [mut 0, ..1024];

    loop {
        let nread = socket.read(buf, buf.len());
        if nread == 0 {
            break;
        }
        chunk.push_all(buf.view(0, nread));
    }

    let encoded_bytes = chunk.encode(encoding::Base64);

    socket.write(encoded_bytes);
}
<commit_msg>Remove the use of deprecated argument mode<commit_after>extern mod std;
extern mod encoding;

use std::net::ip;
use std::net::tcp;
use std::uv_global_loop;

use encoding::{Codec};
use io::{ReaderUtil, WriterUtil};
use tcp::{TcpErrData, TcpNewConnection, TcpSocket};
use task::{SingleThreaded, task};

type KillChan = comm::Chan<Option<TcpErrData>>;
type ContChan = comm::Chan<()>;

fn main() {
    let iotask = uv_global_loop::get();

    let addr = "127.0.0.1";
    let port = 1337;

    let backlog = 128;
    let ip_addr = ip::get_addr(addr, iotask);
    let ip_addr = copy result::unwrap(ip_addr)[0];

    tcp::listen(ip_addr, port, backlog, iotask,
        |kill_ch| on_established(kill_ch),
        |conn, kill_ch| on_new_connection(conn, kill_ch));
}

fn on_established(_kill_ch: KillChan) {
    io::println("running at 127.0.0.1:1337");
}

fn on_new_connection(conn: TcpNewConnection, kill_ch: KillChan) {
    do comm::listen |cont_ch| {
        // Spawn new child which doesn't propagate errors to parent.
        do task().unlinked().sched_mode(SingleThreaded).spawn {
            accept(conn, kill_ch, cont_ch);
        }
        // Wait `tcp::accept(conn)' complete.
        cont_ch.recv();
    }
}

fn accept(conn: TcpNewConnection, kill_ch: KillChan, cont_ch: ContChan) {
    match tcp::accept(conn) {
        Ok(move socket) => {
            cont_ch.send(());
            encode(socket);
        }
        Err(move err_data) => {
            kill_ch.send(Some(err_data));
            cont_ch.send(());
        }
    }
}

fn encode(socket: TcpSocket) {
    let socket = tcp::socket_buf(socket);

    let mut chunk = ~[];
    let mut buf = [mut 0, ..1024];

    loop {
        let nread = socket.read(buf, buf.len());
        if nread == 0 {
            break;
        }
        chunk.push_all(buf.view(0, nread));
    }

    let encoded_bytes = chunk.encode(encoding::Base64);

    socket.write(encoded_bytes);
}
<|endoftext|>