aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTill Hoeppner2014-10-21 15:33:17 +0200
committerTill Hoeppner2014-10-21 16:15:10 +0200
commitfc27f8cee888acf70683badca9edadb45544822c (patch)
treef39314f857e92a1e5a19f9675205750adf8919f0
parentce640c2c25b0e16c567553c5774d633c13cbf0ee (diff)
downloadirsc-fc27f8cee888acf70683badca9edadb45544822c.tar.gz
irsc-fc27f8cee888acf70683badca9edadb45544822c.tar.xz
irsc-fc27f8cee888acf70683badca9edadb45544822c.zip
Initial commit.
-rw-r--r--.gitignore31
-rw-r--r--Makefile33
-rw-r--r--src/color.rs49
-rw-r--r--src/events.rs22
-rw-r--r--src/ident.rs24
-rw-r--r--src/lib.rs13
-rw-r--r--src/main.rs34
-rw-r--r--src/server.rs168
-rw-r--r--src/src/.irsc.rs.swpbin12288 -> 0 bytes
-rw-r--r--src/src/irsc.rs106
-rwxr-xr-xtarget/irscbin1025479 -> 0 bytes
-rwxr-xr-xtarget/rwmbin1177853 -> 0 bytes
12 files changed, 338 insertions, 142 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..245f0b7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,31 @@
+# Created by https://www.gitignore.io
+
+### vim ###
+[._]*.s[a-w][a-z]
+[._]s[a-w][a-z]
+*.un~
+Session.vim
+.netrwhist
+*~
+
+
+### Linux ###
+*~
+
+# KDE directory preferences
+.directory
+
+
+### Rust ###
+# Compiled files
+*.o
+*.so
+*.rlib
+*.dll
+
+# Executables
+*.exe
+
+# Generated by Cargo
+/target/
+
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 58dec28..0000000
--- a/Makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-RUSTC ?= rustc
-RUSTC_FLAGS ?=
-NAME ?= irsc
-
-SRC = $(shell find src -name '*.rs')
-
-all: $(NAME)
-
-$(NAME): $(SRC)
- mkdir -p target
- $(RUSTC) --out-dir target $(RUSTC_FLAGS) src/$(NAME).rs
-
-opt: RUSTC_FLAGS += --opt-level=3 -Z lto
-opt: $(NAME)
-
-small: opt
- upx -9 ./target/$(NAME)
-
-debug: RUSTC_FLAGS += -g
-debug: $(NAME)
-
-run: $(NAME)
- ./target/$(NAME)
-
-test: $(SRC)
- mkdir -p target
- $(RUSTC) --test --out-dir target src/$(NAME).rs
- ./target/$(NAME)
-
-clean:
- @rm -rf target
-
-.PHONY: clean
diff --git a/src/color.rs b/src/color.rs
new file mode 100644
index 0000000..45a5eeb
--- /dev/null
+++ b/src/color.rs
@@ -0,0 +1,49 @@
+pub const WHITE: &'static str = "00";
+pub const BLACK: &'static str = "01";
+pub const BLUE: &'static str = "02";
+pub const GREEN: &'static str = "03";
+pub const RED: &'static str = "04";
+pub const BROWN: &'static str = "05";
+pub const PURPLE: &'static str = "06";
+pub const ORANGE: &'static str = "07";
+pub const YELLOW: &'static str = "08";
+pub const LIME: &'static str = "09";
+pub const TEAL: &'static str = "10";
+pub const LIGHT_CYAN: &'static str = "11";
+pub const LIGHT_BLUE: &'static str = "12";
+pub const PINK: &'static str = "13";
+pub const GREY: &'static str = "14";
+pub const LIGHT_GREY: &'static str = "15";
+
+pub const TRANSPARENT: &'static str = "99";
+
+
+
+
+pub fn normal(s: &str) -> String {
+ format!("\x0F{}\x0F", s)
+}
+
+pub fn bold(s: &str) -> String {
+ format!("\x02{}\x02", s)
+}
+
+pub fn italic(s: &str) -> String {
+ format!("\x1D{}\x1D", s)
+}
+
+pub fn underline(s: &str) -> String {
+ format!("\x1F{}\x1F", s)
+}
+
+pub fn foreground(s: &str, foreground: &str) -> String {
+ format!("\x03{}{}\x03", foreground, s)
+}
+
+pub fn background(s: &str, background: &str) -> String {
+ format!("\x03,{}{}\x03", background, s)
+}
+
+pub fn color(s: &str, foreground: &str, background: &str) -> String {
+ format!("\x03{},{}{}\x03", foreground, background, s)
+}
diff --git a/src/events.rs b/src/events.rs
new file mode 100644
index 0000000..8c474d7
--- /dev/null
+++ b/src/events.rs
@@ -0,0 +1,22 @@
+use ident::Ident;
+
+macro_rules! string_record(
+ ($name: ident, $( $fields: ident ),*) => (
+ #[deriving(Show, Clone)]
+ pub struct $name {
+ $(pub $fields: String),*
+ }
+ )
+)
+
+string_record!(Welcome, source, target, msg)
+string_record!(YourHost, source, target, msg)
+string_record!(Created, source, target, msg)
+
+#[deriving(Show, Clone)]
+pub enum Event {
+ RplWelcome(Box<Welcome>),
+ RplYourHost(Box<YourHost>),
+ RplCreated(Box<Created>),
+ PrivMsg(Ident, String, String)
+}
diff --git a/src/ident.rs b/src/ident.rs
new file mode 100644
index 0000000..069e186
--- /dev/null
+++ b/src/ident.rs
@@ -0,0 +1,24 @@
+use regex::Regex;
+
+static PATTERN: Regex = regex!(":(.*)!(.*)@(.*)");
+
+#[deriving(Show, Clone)]
+pub struct Ident {
+ pub nickname: String,
+ pub user: String,
+ pub host: String
+}
+
+impl Ident {
+ pub fn parse(s: &str) -> Option<Ident> {
+ let c = match PATTERN.captures(s) {
+ Some(c) => c,
+ None => return None
+ };
+ Some(Ident {
+ nickname: c.at(1).into_string(),
+ user: c.at(2).into_string(),
+ host: c.at(3).into_string()
+ })
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index a93251b..fcb0096 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,3 +1,10 @@
-#[test]
-fn it_works() {
-}
+#![feature(globs, phase, slicing_syntax, macro_rules)]
+
+#[phase(plugin)]
+extern crate regex_macros;
+extern crate regex;
+
+pub mod server;
+pub mod events;
+pub mod color;
+pub mod ident;
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..e9965d8
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,34 @@
+#![feature(globs, slicing_syntax)]
+
+extern crate irsc;
+
+use irsc::server::Server;
+use irsc::events::*;
+use irsc::color::bold;
+
+static NAME: &'static str = "rusticbot";
+static DESC: &'static str = "A bot, written in Rust.";
+
+fn main() {
+ let mut s = Server::new("irc.freenode.org".into_string(), 6667);
+ let events = s.events();
+ s.connect().unwrap();
+ s.nick(NAME).unwrap();
+ s.user(NAME, "*", "*", DESC).unwrap();
+ s.join("#botzoo").unwrap();
+
+ s.msg("flan3002", "Hey!").unwrap();
+
+ for e in events.iter() {
+ match e {
+ RplWelcome(welcome) => {
+ println!("{}", welcome)
+ },
+ PrivMsg(from, _to, msg) => {
+ let response = format!("You wrote: {}", bold(msg[]));
+ s.msg(from.nickname[], response[]).unwrap();
+ }
+ _ => ()
+ }
+ }
+}
diff --git a/src/server.rs b/src/server.rs
new file mode 100644
index 0000000..71012ba
--- /dev/null
+++ b/src/server.rs
@@ -0,0 +1,168 @@
+use std::io::{
+ BufferedReader,
+ TcpStream,
+ IoError
+};
+use std::ascii::StrAsciiExt;
+use std::comm;
+use std::comm::{ Sender, Receiver };
+use std::collections::HashMap;
+
+use std::str::UnicodeStrSlice;
+
+use events::*;
+
+use ident::Ident;
+
+fn parse_msg(v: Vec<&str>, from: uint) -> String {
+ let mut msg = if v[from].chars().next().unwrap() == ':' {
+ v[from][1..].into_string()
+ } else { v[from].into_string() };
+ for m in v.iter().skip(from + 1) {
+ msg.push_str(" ");
+ msg.push_str(m.trim_right());
+ }
+ msg
+}
+
+#[deriving(Show, PartialEq, Eq, Clone)]
+pub enum Failure {
+ NotConnected,
+ Io(IoError)
+}
+
+pub struct Context<'a> {
+ prefix: &'a str,
+ command: &'a str,
+ parts: [&'a str]
+}
+
+pub struct Server<'a> {
+ host: String,
+ port: u16,
+ stream: Option<TcpStream>,
+ event_sender: Option<Sender<Event>>,
+ event_types: HashMap<String, &'a Fn<Context<'a>, Event> + 'a>
+}
+
+impl<'a> Server<'a> {
+ pub fn new(host: String, port: u16) -> Server<'a> {
+ Server {
+ host: host,
+ port: port,
+ stream: None,
+ event_sender: None,
+ event_types: HashMap::new()
+ }
+ }
+
+ pub fn events(&mut self) -> Receiver<Event> {
+ let (tx, rx) = comm::channel();
+ self.events = Some(tx);
+ rx
+ }
+
+ fn fire_event(&mut self, event: Event) {
+ self.events.as_ref().map(|s| s.send(event.clone()));
+ }
+
+ pub fn connect(&mut self) -> Result<(), Failure> {
+ self.stream = match TcpStream::connect(self.host.as_slice(), self.port) {
+ Ok(tcp) => Some(tcp),
+ Err(e) => return Err(Io(e))
+ };
+
+ let mut s = self.clone();
+ spawn(proc() {
+ s.listen();
+ });
+ Ok(())
+ }
+
+ #[inline]
+ fn sendraw(&mut self, s: &str, newline: bool) -> Result<(), Failure> {
+ println!("{}", s);
+ if self.stream.is_some() {
+ let mut st = self.stream.clone().unwrap();
+ match st.write_str(s) {
+ Ok(_) => match st.flush() {
+ Ok(_) if newline => match st.write_str("\r\n") {
+ Ok(_) => Ok(()),
+ Err(e) => return Err(Io(e))
+ },
+ Ok(_) => Ok(()),
+ Err(e) => return Err(Io(e))
+ },
+ Err(e) => return Err(Io(e))
+ }
+ } else {
+ Err(NotConnected)
+ }
+ }
+
+ pub fn join(&mut self, channel: &str) -> Result<(), Failure> {
+ self.sendraw(format!("JOIN {}", channel).as_slice(), true)
+ }
+
+ pub fn nick(&mut self, nick: &str) -> Result<(), Failure> {
+ self.sendraw(format!("NICK {}", nick).as_slice(), true)
+ }
+
+ pub fn user(&mut self, username: &str, hostname: &str, servername: &str, realname: &str) -> Result<(), Failure> {
+ self.sendraw(format!("USER {} {} {} :{}", username, hostname, servername, realname).as_slice(), true)
+ }
+
+ pub fn password(&mut self, password: &str) -> Result<(), Failure> {
+ self.sendraw(format!("PASS {}", password).as_slice(), true)
+ }
+
+ pub fn msg(&mut self, target: &str, message: &str) -> Result<(), Failure> {
+ self.sendraw(format!("PRIVMSG {} :{}", target, message).as_slice(), true)
+ }
+
+ fn listen(&mut self) {
+ let stream = match self.stream {
+ Some(ref s) => s.clone(),
+ None => return
+ };
+ let mut reader = BufferedReader::new(stream);
+ loop {
+ let line = reader.read_line().unwrap();
+ let mut parts = line.as_slice().split(' ').collect::<Vec<&str>>();
+ println!("{}", parts);
+ if parts.len() == 0 {
+ continue;
+ }
+
+ // if message has a prefix
+ let prefix = if parts[0].chars().next().unwrap() == ':' {
+ parts.remove(0).unwrap()
+ } else { "" };
+
+ let cmd = parts.remove(0).unwrap();
+ let context = Context { prefix: prefix, cmd: cmd, parts: parts };
+ self.events.entry(cmd).call(&context);
+
+ /*match parts[0].to_ascii_upper().as_slice() {
+ "001" => {
+ self.fire_event(RplWelcome(box Welcome {
+ source: prefix.into_string(),
+ target: parts[1].into_string(),
+ msg: parse_msg(parts, 2)
+ }))
+ },
+ "PING" => {
+ let _ = self.sendraw(format!("PONG {}", parts.get(1)).as_slice(), true);
+ continue;
+ }
+ "PRIVMSG" => {
+ let from = Ident::parse(prefix).unwrap();
+ let to = parts[1];
+ let msg = parse_msg(parts, 2);
+ self.fire_event(PrivMsg(from, to.into_string(), msg))
+ },
+ _ => ()
+ }*/
+ }
+ }
+}
diff --git a/src/src/.irsc.rs.swp b/src/src/.irsc.rs.swp
deleted file mode 100644
index da65aeb..0000000
--- a/src/src/.irsc.rs.swp
+++ /dev/null
Binary files differ
diff --git a/src/src/irsc.rs b/src/src/irsc.rs
deleted file mode 100644
index 704a0f7..0000000
--- a/src/src/irsc.rs
+++ /dev/null
@@ -1,106 +0,0 @@
-use std::io::{
- BufferedReader,
- TcpStream,
- IoResult
-};
-use std::str;
-use std::ascii::StrAsciiExt;
-use std::simd::f32x4;
-
-struct Server {
- host: String,
- port: u16,
- stream: Option<TcpStream>
-}
-
-impl Server {
-
- fn new(host: &str, port: u16) -> Server {
- Server {
- host: String::from_str(host),
- port: port,
- stream: None
- }
- }
-
- fn connect(&mut self) {
- self.stream = Some(TcpStream::connect(self.host.as_slice(), self.port).unwrap());
-
- let cs = self.stream.clone();
- spawn(proc() {
- Server::listen(cs);
- });
- }
-
- #[inline]
- fn sendraw(stream: &mut TcpStream, s: &str) {
- stream.write_str(s);
- stream.flush();
- }
-
- #[inline]
- fn sendrawln(stream: &mut TcpStream, s: &str) {
- Server::sendraw(stream, String::with_capacity(s.len() + 2).append(s).append("\r\n").as_slice());
- }
-
- fn join(self, channel: &str) {
- self.stream.map(|mut st| Server::sendrawln(&mut st, format!("JOIN {}", channel).as_slice()));
- }
-
- fn listen(stream: Option<TcpStream>) {
- let mut abort = false;
- let mut stream = match stream {
- Some(s) => s,
- None => return
- };
- if abort {return;}
- let mut reader = BufferedReader::new(stream.clone());
- loop {
- let line = reader.read_line().unwrap();
- //println!("{}", line);
- let mut parts = line.as_slice().split(' ').collect::<Vec<&str>>();
- println!("{}", parts);
-
- if parts.len() == 0 {
- continue;
- }
-
- // if message has a prefix
- let prefix = if parts.get(0).chars().next().unwrap() == ':' {
- parts.shift().unwrap()
- } else { "" };
-
- match (*parts.get(0)).to_ascii_upper().as_slice() {
- "PING" => {
- Server::sendrawln(&mut stream, format!("PONG {}", parts.get(1)).as_slice());
- continue;
- }
- _ => {}
- }
-
- }
- }
-
-
-}
-
-fn main() {
- let mut furnet = Server::new("irc.furnet.org", 6667);
- furnet.connect();
-
- std::io::timer::sleep(5000u64);
-
- furnet.join("#teenagefurs");
-
- // create simd vectors
- let x = f32x4(1.0, 2.0, 3.0, 4.0);
- let y = f32x4(4.0, 3.0, 2.0, 1.0);
-
- // simd product
- let z = x * y;
-
- // like any struct, the simd vector can be destructured using `let`
- let f32x4(a, b, c, d) = z;
-
- println!("{}", (a, b, c, d));
-}
diff --git a/target/irsc b/target/irsc
deleted file mode 100755
index 49a26f5..0000000
--- a/target/irsc
+++ /dev/null
Binary files differ
diff --git a/target/rwm b/target/rwm
deleted file mode 100755
index b3b0a9e..0000000
--- a/target/rwm
+++ /dev/null
Binary files differ