changeset 0:46810d1d1a0a draft

Initial commit Basic syslog enums are implemented.
author Lewin Bormann <lbo@spheniscida.de>
date Sat, 26 Nov 2016 10:23:17 +0100
parents
children 03aa381b5c1c
files .hgignore Cargo.toml src/main.rs src/priority.rs
diffstat 4 files changed, 142 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Sat Nov 26 10:23:17 2016 +0100
@@ -0,0 +1,1 @@
+target
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Cargo.toml	Sat Nov 26 10:23:17 2016 +0100
@@ -0,0 +1,6 @@
+[package]
+name = "syslogd"
+version = "0.1.0"
+authors = ["Lewin Bormann <lewin@lewin-bormann.info>"]
+
+[dependencies]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main.rs	Sat Nov 26 10:23:17 2016 +0100
@@ -0,0 +1,5 @@
+mod priority;
+
+fn main() {
+    println!("Hello, world!");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/priority.rs	Sat Nov 26 10:23:17 2016 +0100
@@ -0,0 +1,130 @@
+#![allow(dead_code)]
+
+use std::str::FromStr;
+
+#[derive(Debug,  PartialEq)]
+pub enum Level {
+    EMERG = 0,
+    ALERT = 1,
+    CRIT = 2,
+    ERR = 3,
+    WARNING = 4,
+    NOTICE = 5,
+    INFO = 6,
+    DEBUG = 7,
+}
+
+pub fn to_level(l: i32) -> Option<Level> {
+    if l >= Level::EMERG as i32 && l <= Level::DEBUG as i32 {
+        Some(match l {
+            0 => Level::EMERG,
+            1 => Level::ALERT,
+            2 => Level::CRIT,
+            3 => Level::ERR,
+            4 => Level::WARNING,
+            5 => Level::NOTICE,
+            6 => Level::INFO,
+            7 => Level::DEBUG,
+            _ => panic!("Bug: unexpected value"),
+        })
+    } else {
+        None
+    }
+}
+
+#[derive(Debug,  PartialEq)]
+pub enum Facility {
+    KERN = 0,
+    USER = 1,
+    MAIL = 2,
+    DAEMON = 3,
+    AUTH = 4,
+    SYSLOG = 5,
+    LPR = 6,
+    NEWS = 7,
+    UUCP = 8,
+    CRON = 9,
+    AUTHPRIV = 10,
+    FTP = 11,
+
+    LOCAL0 = 16,
+    LOCAL1 = 17,
+    LOCAL2 = 18,
+    LOCAL3 = 19,
+    LOCAL4 = 20,
+    LOCAL5 = 21,
+    LOCAL6 = 22,
+    LOCAL7 = 23,
+}
+
+pub fn to_facility(l: i32) -> Option<Facility> {
+    if (l >= Facility::KERN as i32 && l <= Facility::FTP as i32) ||
+       (l >= Facility::LOCAL0 as i32 && l <= Facility::LOCAL7 as i32) {
+        Some(match l {
+            0 => Facility::KERN,
+            1 => Facility::USER,
+            2 => Facility::MAIL,
+            3 => Facility::DAEMON,
+            4 => Facility::AUTH,
+            5 => Facility::SYSLOG,
+            6 => Facility::LPR,
+            7 => Facility::NEWS,
+            8 => Facility::UUCP,
+            9 => Facility::CRON,
+            10 => Facility::AUTHPRIV,
+            11 => Facility::FTP,
+            16 => Facility::LOCAL0,
+            17 => Facility::LOCAL1,
+            18 => Facility::LOCAL2,
+            19 => Facility::LOCAL3,
+            20 => Facility::LOCAL4,
+            21 => Facility::LOCAL5,
+            22 => Facility::LOCAL6,
+            23 => Facility::LOCAL7,
+            _ => panic!("Bug: unexpected value"),
+        })
+    } else {
+        None
+    }
+}
+
+
+/// Converts a (level, facility) pair into a decimal number
+pub fn lf_to_priority(l: Level, f: Facility) -> i32 {
+    l as i32 + 8 * f as i32
+}
+
+/// Converts a decimal number string into a pair of level, facility
+pub fn parse(prio: &str) -> Option<(Level, Facility)> {
+    match i32::from_str(prio) {
+        Ok(l) => priority_to_lf(l),
+        Err(_) => None,
+    }
+}
+
+pub fn priority_to_lf(prio: i32) -> Option<(Level, Facility)> {
+    let level = prio & 0b111;
+    let fac = prio >> 3;
+
+    match (to_level(level), to_facility(fac)) {
+        (Some(l), Some(f)) => Some((l, f)),
+        _ => None,
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_priority_combine() {
+        assert_eq!(20, lf_to_priority(Level::WARNING, Facility::MAIL));
+        assert_eq!(35, lf_to_priority(Level::ERR, Facility::AUTH));
+    }
+
+    #[test]
+    fn test_priority_parse() {
+        let priostr = format!("{}", lf_to_priority(Level::WARNING, Facility::NEWS));
+        assert_eq!(parse(&priostr), Some((Level::WARNING, Facility::NEWS)));
+    }
+}