<commit_before>use seed::prelude::*;
use crate::Msg;

pub mod mersenne_utils {
    extern crate num_bigint;
    extern crate num_traits;

    use num_traits::{Pow,Num};
    use num_bigint::{BigInt,ToBigInt};

    pub fn mersennes_discovery_dates(n:usize) -> String {
        let mersennes_discovery_dates:Vec<Vec<&str>> = vec![
            //TODO: Complete this list all the way upto 50
            //TODO: We could include download links etc
            vec![""],//faux zero entry to make things easier when reading this vector
            vec!["500BC"],
            vec!["500BC"],
            vec!["275BC"],
            vec!["275BC"],
            vec!["1456"],
            vec!["1588"],
            vec!["1588"],
            vec!["1772"],
            vec!["1883"],
            vec!["1911"],
            vec!["1914"],
            vec!["1876"],
            vec!["30-Jan-1952"],
            vec!["30-Jan-1952"],
            vec!["26-Jun-1952"],
            vec!["7-Oct-1952"],
            vec!["9-Oct-1952"],
            vec!["8-Sep-1957"],
            vec!["3-Nov-1961"],
            vec!["3-Nov-1961"],
            vec!["11-May-1963"],
            vec!["16-May-1963"],
            vec!["2-Jun-1963"],
            vec!["4-Mar-1971"],
            vec!["30-Oct-1978"],
            vec!["9-Feb-1979"],
            vec!["8-Apr-1979"],
            vec!["25-Sep-1982"],
            vec!["28-Jan-1988"],
            vec!["20-Sep-1983"],
            vec!["6-Sep-1985"],
            vec!["19-Feb-1992"],
            vec!["10-Jan-1994"],
            vec!["3-Sep-1996"],
            vec!["12-Nov-1996"],
            vec!["24-Aug-1997"],
            vec!["27-Jan-1998"],
            vec!["1-Jun-1999"],
            vec!["14-Nov-2001"],
            vec!["17-Nov-2003"],
            vec!["28-May-2004"],
            vec!["26-Feb-2005"],
            vec!["15-Dec-2005"],
            vec!["4-Sep-2006"],
            vec!["23-Aug-2008"],
            vec!["06-Sep-2009"],
            vec!["12-Apr-2008"],
            vec!["25-Jan-2013"],
            vec!["07-Jan-2016"],
            vec!["26-Dec-2017"],
        ];

        mersennes_discovery_dates[n][0].to_owned()
    }

    pub fn mersennes() -> Vec<Vec<usize>> {
        vec![
            //vec![p,digits]
            vec![0,     0],//faux zero entry to make things easier when reading this vector
            vec![2,     1],
            vec![3,     1],
            vec![5,     2],
            vec![7,     3],
            vec![13,    4],
            vec![17,    6],
            vec![19,    6],
            vec![31,   10],
            vec![61,   19],
            vec![89,   27],
            vec![107,  33],
            vec![127,  39],
            vec![521,  157],
            vec![607,  183],
            vec![1279, 386],
            vec![2203, 664],
            vec![2281, 687],
            vec![3217, 969],
            vec![4253,1281],
            vec![4423,1332],
            vec![9689,2917],
            vec![9941,2993],
            vec![11213,3376],
            vec![19937,6002],
            vec![21701,6533],
            vec![23209,6987],
            vec![44497,13395],
            vec![86243,25962],
            vec![110503,33265],
            vec![132049,39751],
            vec![216091,65050],
            vec![756839,227832],
            vec![859433,258716],
            vec![1257787,378632],
            vec![1398269,420921],
            vec![2976221,895832],
            vec![3021377,909526],
            vec![6972593,2098960],
            vec![13466917,4053946],
            vec![20996011,6320430],
            vec![24036583,7235733],
            vec![25964951,7816230],
            vec![30402457,9152052],
            vec![32582657,9808358],
            vec![37156667,11185272],
            vec![42643801,12837064],
            vec![43112609,12978189],
            vec![57885161,17425170],
            vec![74207281,22338618],
            vec![77232917,23249425],
        ]
    }

    pub fn nth_mersenne_prime (candidate:&str) -> u64 {
        let big_candidate:BigInt = num_bigint::BigInt::from_str_radix(&candidate, 10).unwrap();
        let mersennes:Vec<Vec<usize>> = mersennes();

        let mut answer:u64 = 0;
        let big_two:BigInt = 2.to_bigint().unwrap();
        for n in 1..mersennes.len() {
            let mprime:BigInt = big_two.pow(mersennes[n][0]) - 1;
            if big_candidate == mprime {
                answer = n as u64;
                break
            } else if big_candidate < mprime {
                break
            }
        }

        answer
    }
}

pub fn render(model: &crate::Model) -> seed::dom_types::Node<Msg> {
    let mut html = vec![];
    let mersennes = mersenne_utils::mersennes();

    for n in 1..mersennes.len() {
        let download_txt:String = format!("https://static.bigprimes.net/archive/mersenne/M{}.txt",&n.to_string());
        let download_zip:String = format!("https://static.bigprimes.net/archive/mersenne/M{}.zip",&n.to_string());
        html.push(
            tr![
                td![n.to_string()],
                td!["2",sup![mersennes[n][0].to_string()],"-1"],
                td![mersennes[n][1].to_string()],
                td![mersenne_utils::mersennes_discovery_dates(n)],
                if n >= 30 {a![attrs!{At::Href => download_zip},"ZIP"]} else {a![attrs!{At::Href => download_txt},"TXT"]}
            ]
        );
    }

    html.reverse();

    div![
        h1!["The Mersenne Numbers"],
        br![],
        br![],
        br![],
        table![
            attrs!{At::Class => "mersennetable text"},
            tbody![
                tr![
                    td![
                        b!["No."]
                    ],
                    td![
                        b!["Prime"]
                    ],
                    td![
                        b!["Digits"]
                    ],
                    td![
                        b!["Discovered"]
                    ],
                    td![
                        b!["Download"]
                    ]
                ],
                html
            ]
        ]
    ]
}

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

    #[test]
    fn mersennes_discovery_dates_test() {
        assert_eq!(mersenne_utils::mersennes_discovery_dates(0), "");
        assert_eq!(mersenne_utils::mersennes_discovery_dates(50), "26-Dec-2017");
    }

    #[test]
    fn nth_mersenne_prime_test() {
        assert_eq!(mersenne_utils::nth_mersenne_prime("127"), 4);
        assert_eq!(mersenne_utils::nth_mersenne_prime("9"), 0);
    }

    #[test]
    fn mersenne_test() {
        let mersennes:Vec<Vec<usize>> = mersenne_utils::mersennes();
        assert_eq!(mersennes[0][0], 0);
        assert_eq!(mersennes[0][1], 0);

        assert_eq!(mersennes[2][0], 3);
        assert_eq!(mersennes[2][1], 1);
    }
}<commit_msg>Added Mersenne struct. Updated everything in the page to support using the struct.<commit_after>use seed::prelude::*;
use crate::Msg;

pub mod mersenne_utils {
    extern crate num_bigint;
    extern crate num_traits;

    use num_traits::{Pow,Num};
    use num_bigint::{BigInt,ToBigInt};

    #[derive(Clone)]
	pub struct Mersenne {
		pub n: u64,
		pub p: u64,
		pub digits: u64,
		pub discovery: String,
	}

    pub fn mersennes_discovery_dates(n:usize) -> String {
        let mersennes_discovery_dates:Vec<Mersenne> = mersennes();

        mersennes_discovery_dates[n].discovery.to_owned()
    }

    pub fn mersennes() -> Vec<Mersenne> {
        vec![
            //vec![p,digits]
            Mersenne {n: 0, p: 0, digits: 0, discovery: String::from("")},//faux zero entry to make things easier when reading this vector
            Mersenne {n: 1, p: 2, digits: 1, discovery: String::from("500BC")},
            Mersenne {n: 2, p: 3, digits: 1, discovery: String::from("500BC")},
            Mersenne {n: 3, p: 5, digits: 2, discovery: String::from("275BC")},
            Mersenne {n: 4, p: 7, digits: 3, discovery: String::from("275BC")},
            Mersenne {n: 5, p: 13, digits: 4, discovery: String::from("1456")},
            Mersenne {n: 6, p: 17, digits: 6, discovery: String::from("1588")},
            Mersenne {n: 7, p: 19, digits: 6, discovery: String::from("1588")},
            Mersenne {n: 8, p: 31, digits: 10, discovery: String::from("1772")},
            Mersenne {n: 9, p: 61, digits: 19, discovery: String::from("1883")},
            Mersenne {n: 10, p: 89, digits: 27, discovery: String::from("1911")},
            Mersenne {n: 11, p: 107, digits: 33, discovery: String::from("1914")},
            Mersenne {n: 12, p: 127, digits: 39, discovery: String::from("1876")},
            Mersenne {n: 13, p: 521, digits: 157, discovery: String::from("30-Jan-1952")},
            Mersenne {n: 14, p: 607, digits: 183, discovery: String::from("30-Jan-1952")},
            Mersenne {n: 15, p: 1279, digits: 386, discovery: String::from("26-Jun-1952")},
            Mersenne {n: 16, p: 2203, digits: 664, discovery: String::from(" 7-Oct-1952")},
            Mersenne {n: 17, p: 2281, digits: 687, discovery: String::from(" 9-Oct-1952")},
            Mersenne {n: 18, p: 3217, digits: 969, discovery: String::from(" 8-Sep-1957")},
            Mersenne {n: 19, p: 4253, digits: 1281, discovery: String::from(" 3-Nov-1961")},
            Mersenne {n: 20, p: 4423, digits: 1332, discovery: String::from(" 3-Nov-1961")},
            Mersenne {n: 21, p: 9689, digits: 2917, discovery: String::from("11-May-1963")},
            Mersenne {n: 22, p: 9941, digits: 2993, discovery: String::from("16-May-1963")},
            Mersenne {n: 23, p: 11213, digits: 3376, discovery: String::from(" 2-Jun-1963")},
            Mersenne {n: 24, p: 19937, digits: 6002, discovery: String::from(" 4-Mar-1971")},
            Mersenne {n: 25, p: 21701, digits: 6533, discovery: String::from("30-Oct-1978")},
            Mersenne {n: 26, p: 23209, digits: 6987, discovery: String::from(" 9-Feb-1979")},
            Mersenne {n: 27, p: 44497, digits: 13395, discovery: String::from(" 8-Apr-1979")},
            Mersenne {n: 28, p: 86243, digits: 25962, discovery: String::from("25-Sep-1982")},
            Mersenne {n: 29, p: 110503, digits: 33265, discovery: String::from("28-Jan-1988")},
            Mersenne {n: 30, p: 132049, digits: 39751, discovery: String::from("20-Sep-1983")},
            Mersenne {n: 31, p: 216091, digits: 65050, discovery: String::from(" 6-Sep-1985")},
            Mersenne {n: 32, p: 756839, digits: 227832, discovery: String::from("19-Feb-1992")},
            Mersenne {n: 33, p: 859433, digits: 258716, discovery: String::from("10-Jan-1994")},
            Mersenne {n: 34, p: 1257787, digits: 378632, discovery: String::from(" 3-Sep-1996")},
            Mersenne {n: 35, p: 1398269, digits: 420921, discovery: String::from("12-Nov-1996")},
            Mersenne {n: 36, p: 2976221, digits: 895832, discovery: String::from("24-Aug-1997")},
            Mersenne {n: 37, p: 3021377, digits: 909526, discovery: String::from("27-Jan-1998")},
            Mersenne {n: 38, p: 6972593, digits: 2098960, discovery: String::from(" 1-Jun-1999")},
            Mersenne {n: 39, p: 13466917, digits: 4053946, discovery: String::from("14-Nov-2001")},
            Mersenne {n: 40, p: 20996011, digits: 6320430, discovery: String::from("17-Nov-2003")},
            Mersenne {n: 41, p: 24036583, digits: 7235733, discovery: String::from("28-May-2004")},
            Mersenne {n: 42, p: 25964951, digits: 7816230, discovery: String::from("26-Feb-2005")},
            Mersenne {n: 43, p: 30402457, digits: 9152052, discovery: String::from("15-Dec-2005")},
            Mersenne {n: 44, p: 32582657, digits: 9808358, discovery: String::from(" 4-Sep-2006")},
            Mersenne {n: 45, p: 37156667, digits: 11185272, discovery: String::from("23-Aug-2008")},
            Mersenne {n: 46, p: 42643801, digits: 12837064, discovery: String::from("06-Sep-2009")},
            Mersenne {n: 47, p: 43112609, digits: 12978189, discovery: String::from("12-Apr-2008")},
            Mersenne {n: 48, p: 57885161, digits: 17425170, discovery: String::from("25-Jan-2013")},
            Mersenne {n: 49, p: 74207281, digits: 22338618, discovery: String::from("07-Jan-2016")},
            Mersenne {n: 50, p: 77232917, digits: 23249425, discovery: String::from("26-Dec-2017")},
        ]
    }

    pub fn nth_mersenne_prime (candidate:&str) -> u64 {
        let big_candidate:BigInt = num_bigint::BigInt::from_str_radix(&candidate, 10).unwrap();
        let mersennes:Vec<Mersenne> = mersennes();

        let mut answer:u64 = 0;
        let big_two:BigInt = 2.to_bigint().unwrap();
        for n in 1..mersennes.len() {
            let mprime:BigInt = big_two.pow(mersennes[n].p) - 1;
            if big_candidate == mprime {
                answer = n as u64;
                break
            } else if big_candidate < mprime {
                break
            }
        }

        answer
    }
}

pub fn render(model: &crate::Model) -> seed::dom_types::Node<Msg> {
    let mut html = vec![];
    let mersennes = mersenne_utils::mersennes();

    for n in 1..mersennes.len() {
        let download_txt:String = format!("https://static.bigprimes.net/archive/mersenne/M{}.txt",&n.to_string());
        let download_zip:String = format!("https://static.bigprimes.net/archive/mersenne/M{}.zip",&n.to_string());
        html.push(
            tr![
                td![n.to_string()],
                td!["2",sup![mersennes[n].p.to_string()],"-1"],
                td![mersennes[n].digits.to_string()],
                td![mersenne_utils::mersennes_discovery_dates(n)],
                if n >= 30 {a![attrs!{At::Href => download_zip},"ZIP"]} else {a![attrs!{At::Href => download_txt},"TXT"]}
            ]
        );
    }

    html.reverse();

    div![
        h1!["The Mersenne Numbers"],
        br![],
        br![],
        br![],
        table![
            attrs!{At::Class => "mersennetable text"},
            tbody![
                tr![
                    td![
                        b!["No."]
                    ],
                    td![
                        b!["Prime"]
                    ],
                    td![
                        b!["Digits"]
                    ],
                    td![
                        b!["Discovered"]
                    ],
                    td![
                        b!["Download"]
                    ]
                ],
                html
            ]
        ]
    ]
}

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

    #[test]
    fn mersennes_discovery_dates_test() {
        assert_eq!(mersenne_utils::mersennes_discovery_dates(0), "");
        assert_eq!(mersenne_utils::mersennes_discovery_dates(50), "26-Dec-2017");
    }

    #[test]
    fn nth_mersenne_prime_test() {
        assert_eq!(mersenne_utils::nth_mersenne_prime("127"), 4);
        assert_eq!(mersenne_utils::nth_mersenne_prime("9"), 0);
    }

    #[test]
    fn mersenne_test() {
        let mersennes:Vec<mersenne_utils::Mersenne> = mersenne_utils::mersennes();
        assert_eq!(mersennes[0].p, 0);
        assert_eq!(mersennes[0].digits, 0);

        assert_eq!(mersennes[2].p, 3);
        assert_eq!(mersennes[2].digits, 1);
    }
}<|endoftext|>


<commit_before>use seed::prelude::*;
use crate::Msg;

pub mod perfects_utils {
	use num_bigint::{BigUint,ToBigUint};
	use num_traits::{ToPrimitive};
    use seed::prelude::*;
    use crate::Msg;

	#[derive(Clone)]
	pub struct Perfect {
		pub n: u64,
		pub p: u64,
		pub digits: u64,
		pub discovery: String,
	}

	#[derive(Clone)]
	pub struct PerfectDownload {
		pub n: u64,
		pub p: u64,
	}

	pub fn perfects() -> Vec<Perfect> {
        vec![
			Perfect {n: 51, p: 82589934, digits: 49724095, discovery: String::from("2018 Laroche, Woltman, Kurowski, Blosser, et al.")},
			Perfect {n: 50, p: 77232917, digits: 46498850, discovery: String::from("2017 Jonathan Pace, George Woltman, Scott Kurowski, Aaron Blosser, et al..") },
			Perfect {n: 49, p: 74207281, digits: 44677235, discovery: String::from("2016 Cooper, Woltman, Kurowski, Blosser et al.") },
			Perfect {n: 48, p: 57885161, digits: 34850340, discovery: String::from("2013 Cooper, Woltman, Kurowski, et al.") },
			Perfect {n: 47, p: 43112609, digits: 25956377, discovery: String::from("2008 Smith, Woltman, Kurowski, et al.") },
			Perfect {n: 46, p: 42643801, digits: 42643801, discovery: String::from("2009 Strindmo, Woltman, Kurowski, et al.") },
			Perfect {n: 45, p: 37156667, digits: 22370543, discovery: String::from("2008 Elvenich, Woltman, Kurowski, et al.") },
			Perfect {n: 44, p: 32582657, digits: 19616714, discovery: String::from("2006 Cooper, Boone, Woltman, Kurowski, et al.") },
			Perfect {n: 43, p: 30402457, digits: 18304103, discovery: String::from("2005 Cooper, Boone, Woltman, Kurowski, et al.") },
			Perfect {n: 42, p: 25964951, digits: 15632458, discovery: String::from("2005 Nowak, Woltman, Kurowski, et. al.") },
			Perfect {n: 41, p: 24036583, digits: 14471465, discovery: String::from("2004 Findley, Woltman, Kurowski, et. al.") },
			Perfect {n: 40, p: 20996011, digits: 12640858, discovery: String::from("2003 Shafer, Woltman, Kurowski, et. al.") },
			Perfect {n: 39, p: 13466917, digits: 8107892, discovery: String::from("2001 Cameron, Woltman, Kurowski, et. al.") },
			Perfect {n: 38, p: 6972593, digits: 4197919, discovery: String::from("1999 Hajratwala, Woltman, Kurowski, et. al.") },
			Perfect {n: 37, p: 3021377, digits: 1819050, discovery: String::from("1998 Clarkson, Woltman, Kurowski, et. al.") },
			Perfect {n: 36, p: 2976221, digits: 1791864, discovery: String::from("1997 Spence, Woltman, et. al.") },
			Perfect {n: 35, p: 1398269, digits: 841842, discovery: String::from("1996 Armengaud, Woltman, et. al.") },
			Perfect {n: 34, p: 1257787, digits: 757263, discovery: String::from("1996 Slowinski&Gage") },
			Perfect {n: 33, p: 859433, digits: 517430, discovery: String::from("1994 Slowinski&Gage") },
			Perfect {n: 32, p: 756839, digits: 455663, discovery: String::from("1992 Slowinski&Gage") },
			Perfect {n: 31, p: 216091, digits: 130100, discovery: String::from("1985 Slowinski") },
			Perfect {n: 30, p: 132049, digits: 79502, discovery: String::from("1983 Slowinski") },
			Perfect {n: 29, p: 110503, digits: 66530, discovery: String::from("1988 Colquitt&Welsh") },
			Perfect {n: 28, p: 86243, digits: 51924, discovery: String::from("1982 Slowinski") },
			Perfect {n: 27, p: 44497, digits: 26790, discovery: String::from("1979 Nelson&Slowinski") },
			Perfect {n: 26, p: 23209, digits: 13973, discovery: String::from("1979 Noll") },
			Perfect {n: 25, p: 21701, digits: 13066, discovery: String::from("1978 Noll&Nickel") },
			Perfect {n: 24, p: 19937, digits: 12003, discovery: String::from("1971 Tuckerman") },
			Perfect {n: 23, p: 11213, digits: 6751, discovery: String::from("1963 Gillies") },
			Perfect {n: 22, p: 9941, digits: 5985, discovery: String::from("1963 Gillies") },
			Perfect {n: 21, p: 9689, digits: 5834, discovery: String::from("1963 Gillies") },
			Perfect {n: 20, p: 4423, digits: 2663, discovery: String::from("1961 Hurwitz") },
			Perfect {n: 19, p: 4253, digits: 2561, discovery: String::from("1961 Hurwitz") },
			Perfect {n: 18, p: 3217, digits: 1937, discovery: String::from("1957 Riesel") },
			Perfect {n: 17, p: 2281, digits: 1373, discovery: String::from("1952 Robinson") },
			Perfect {n: 16, p: 2203, digits: 1327, discovery: String::from("1952 Robinson") },
			Perfect {n: 14, p: 607, digits: 366, discovery: String::from("1952 Robinson") },
			Perfect {n: 13, p: 521, digits: 314, discovery: String::from("1952 Robinson") },
			Perfect {n: 12, p: 127, digits: 77, discovery: String::from("1876 Lucas") },
			Perfect {n: 11, p: 107, digits: 65, discovery: String::from("1914 Powers") },
			Perfect {n: 10, p: 89, digits: 54, discovery: String::from("1911 Powers") },
			Perfect {n: 9, p: 61, digits: 37, discovery: String::from("1883 Pervushin") },
			Perfect {n: 8, p: 31, digits: 19, discovery: String::from("1772 Euler") },
			Perfect {n: 7, p: 19, digits: 12, discovery: String::from("1588 Cataldi") },
			Perfect {n: 6, p: 17, digits: 10, discovery: String::from("1588 Cataldi") },
			Perfect {n: 5, p: 13, digits: 8, discovery: String::from("1456 ?") },
			Perfect {n: 4, p: 7, digits: 4, discovery: String::from("?") },
			Perfect {n: 3, p: 5, digits: 3, discovery: String::from("?") },
			Perfect {n: 2, p: 3, digits: 2, discovery: String::from("?") },
			Perfect {n: 1, p: 2, digits: 1, discovery: String::from("?") },
		]
	}

	pub fn save_as_file(filename:String, filecontent:String) -> seed::dom_types::Node<Msg> {
        let href:String = vec!["data:text/plain,",&filecontent].into_iter().collect();
        a![attrs!{At::Download => &filename, At::Href => &href}, "TXT"]
    }

	pub fn generate_file(n:u64, p:u64) -> seed::dom_types::Node<Msg> {
		let download_filename:String = format!("P{}.txt",&n.to_string());
		let two:BigUint = 2.to_biguint().unwrap();
		let power:BigUint = two.clone() << (p.to_usize().unwrap()-1-1);
        let perfect_value:BigUint = power.clone() * ((power.clone()*two.clone()) -1.to_biguint().unwrap());
        save_as_file(download_filename, perfect_value.to_string())
    }
}

pub fn render(model: &crate::Model) -> seed::dom_types::Node<Msg> {
    let mut html = vec![];
    let perfects = perfects_utils::perfects().to_owned();

    for perfect in perfects.iter() {
		let perfectp:u64 = perfect.p;
		let perfect_download = perfects_utils::PerfectDownload {n: perfect.n, p: perfect.p};
		let equation:String = format!("2{} × (2{}-1)",&(perfectp-1).to_string(),&(perfectp).to_string());

        html.push(
            tr![
                td![perfect.n.to_string()],//rank
				td![El::from_html(&equation)],//perfect number as a formula

                td![perfect.digits.to_string()],//digits in length
                td![perfect.discovery],//discovery
				if model.download.n == perfect.n {
					perfects_utils::generate_file(model.download.n,model.download.p)
				} else {
					td![button!["Generate",mouse_ev("mouseup", move |event| Msg::GenerateDownload(event, perfect_download))]]
				},
            ]
        );
    }

    div![
        h1!["The Perfect Numbers"],
        br![],
        br![],
        br![],
        table![
            attrs!{At::Class => "perfecttable text"},
            tbody![
                tr![
                    td![
                        b!["No."]
                    ],
                    td![
                        b!["Prime"]
                    ],
                    td![
                        b!["Digits"]
                    ],
                    td![
                        b!["Discovered"]
                    ],
                    td![
                        b!["Download"]
                    ]
                ],
                html
            ]
        ]
    ]
}

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

    #[test]
    fn perfect_test<'a>() {
        let mut perfects:Vec<perfects_utils::Perfect> = perfects_utils::perfects();
		perfects.reverse();
        assert_eq!(perfects[49].digits, 46498850);
        assert_eq!(perfects[39].digits, 12640858);
    }
}<commit_msg>Correcting table layout when TXT download link appears<commit_after>use seed::prelude::*;
use crate::Msg;

pub mod perfects_utils {
	use num_bigint::{BigUint,ToBigUint};
	use num_traits::{ToPrimitive};
    use seed::prelude::*;
    use crate::Msg;

	#[derive(Clone)]
	pub struct Perfect {
		pub n: u64,
		pub p: u64,
		pub digits: u64,
		pub discovery: String,
	}

	#[derive(Clone)]
	pub struct PerfectDownload {
		pub n: u64,
		pub p: u64,
	}

	pub fn perfects() -> Vec<Perfect> {
        vec![
			Perfect {n: 51, p: 82589934, digits: 49724095, discovery: String::from("2018 Laroche, Woltman, Kurowski, Blosser, et al.")},
			Perfect {n: 50, p: 77232917, digits: 46498850, discovery: String::from("2017 Jonathan Pace, George Woltman, Scott Kurowski, Aaron Blosser, et al..") },
			Perfect {n: 49, p: 74207281, digits: 44677235, discovery: String::from("2016 Cooper, Woltman, Kurowski, Blosser et al.") },
			Perfect {n: 48, p: 57885161, digits: 34850340, discovery: String::from("2013 Cooper, Woltman, Kurowski, et al.") },
			Perfect {n: 47, p: 43112609, digits: 25956377, discovery: String::from("2008 Smith, Woltman, Kurowski, et al.") },
			Perfect {n: 46, p: 42643801, digits: 42643801, discovery: String::from("2009 Strindmo, Woltman, Kurowski, et al.") },
			Perfect {n: 45, p: 37156667, digits: 22370543, discovery: String::from("2008 Elvenich, Woltman, Kurowski, et al.") },
			Perfect {n: 44, p: 32582657, digits: 19616714, discovery: String::from("2006 Cooper, Boone, Woltman, Kurowski, et al.") },
			Perfect {n: 43, p: 30402457, digits: 18304103, discovery: String::from("2005 Cooper, Boone, Woltman, Kurowski, et al.") },
			Perfect {n: 42, p: 25964951, digits: 15632458, discovery: String::from("2005 Nowak, Woltman, Kurowski, et. al.") },
			Perfect {n: 41, p: 24036583, digits: 14471465, discovery: String::from("2004 Findley, Woltman, Kurowski, et. al.") },
			Perfect {n: 40, p: 20996011, digits: 12640858, discovery: String::from("2003 Shafer, Woltman, Kurowski, et. al.") },
			Perfect {n: 39, p: 13466917, digits: 8107892, discovery: String::from("2001 Cameron, Woltman, Kurowski, et. al.") },
			Perfect {n: 38, p: 6972593, digits: 4197919, discovery: String::from("1999 Hajratwala, Woltman, Kurowski, et. al.") },
			Perfect {n: 37, p: 3021377, digits: 1819050, discovery: String::from("1998 Clarkson, Woltman, Kurowski, et. al.") },
			Perfect {n: 36, p: 2976221, digits: 1791864, discovery: String::from("1997 Spence, Woltman, et. al.") },
			Perfect {n: 35, p: 1398269, digits: 841842, discovery: String::from("1996 Armengaud, Woltman, et. al.") },
			Perfect {n: 34, p: 1257787, digits: 757263, discovery: String::from("1996 Slowinski&Gage") },
			Perfect {n: 33, p: 859433, digits: 517430, discovery: String::from("1994 Slowinski&Gage") },
			Perfect {n: 32, p: 756839, digits: 455663, discovery: String::from("1992 Slowinski&Gage") },
			Perfect {n: 31, p: 216091, digits: 130100, discovery: String::from("1985 Slowinski") },
			Perfect {n: 30, p: 132049, digits: 79502, discovery: String::from("1983 Slowinski") },
			Perfect {n: 29, p: 110503, digits: 66530, discovery: String::from("1988 Colquitt&Welsh") },
			Perfect {n: 28, p: 86243, digits: 51924, discovery: String::from("1982 Slowinski") },
			Perfect {n: 27, p: 44497, digits: 26790, discovery: String::from("1979 Nelson&Slowinski") },
			Perfect {n: 26, p: 23209, digits: 13973, discovery: String::from("1979 Noll") },
			Perfect {n: 25, p: 21701, digits: 13066, discovery: String::from("1978 Noll&Nickel") },
			Perfect {n: 24, p: 19937, digits: 12003, discovery: String::from("1971 Tuckerman") },
			Perfect {n: 23, p: 11213, digits: 6751, discovery: String::from("1963 Gillies") },
			Perfect {n: 22, p: 9941, digits: 5985, discovery: String::from("1963 Gillies") },
			Perfect {n: 21, p: 9689, digits: 5834, discovery: String::from("1963 Gillies") },
			Perfect {n: 20, p: 4423, digits: 2663, discovery: String::from("1961 Hurwitz") },
			Perfect {n: 19, p: 4253, digits: 2561, discovery: String::from("1961 Hurwitz") },
			Perfect {n: 18, p: 3217, digits: 1937, discovery: String::from("1957 Riesel") },
			Perfect {n: 17, p: 2281, digits: 1373, discovery: String::from("1952 Robinson") },
			Perfect {n: 16, p: 2203, digits: 1327, discovery: String::from("1952 Robinson") },
			Perfect {n: 14, p: 607, digits: 366, discovery: String::from("1952 Robinson") },
			Perfect {n: 13, p: 521, digits: 314, discovery: String::from("1952 Robinson") },
			Perfect {n: 12, p: 127, digits: 77, discovery: String::from("1876 Lucas") },
			Perfect {n: 11, p: 107, digits: 65, discovery: String::from("1914 Powers") },
			Perfect {n: 10, p: 89, digits: 54, discovery: String::from("1911 Powers") },
			Perfect {n: 9, p: 61, digits: 37, discovery: String::from("1883 Pervushin") },
			Perfect {n: 8, p: 31, digits: 19, discovery: String::from("1772 Euler") },
			Perfect {n: 7, p: 19, digits: 12, discovery: String::from("1588 Cataldi") },
			Perfect {n: 6, p: 17, digits: 10, discovery: String::from("1588 Cataldi") },
			Perfect {n: 5, p: 13, digits: 8, discovery: String::from("1456 ?") },
			Perfect {n: 4, p: 7, digits: 4, discovery: String::from("?") },
			Perfect {n: 3, p: 5, digits: 3, discovery: String::from("?") },
			Perfect {n: 2, p: 3, digits: 2, discovery: String::from("?") },
			Perfect {n: 1, p: 2, digits: 1, discovery: String::from("?") },
		]
	}

	pub fn save_as_file(filename:String, filecontent:String) -> seed::dom_types::Node<Msg> {
        let href:String = vec!["data:text/plain,",&filecontent].into_iter().collect();
        a![attrs!{At::Download => &filename, At::Href => &href}, "TXT"]
    }

	pub fn generate_file(n:u64, p:u64) -> seed::dom_types::Node<Msg> {
		let download_filename:String = format!("P{}.txt",&n.to_string());
		let two:BigUint = 2.to_biguint().unwrap();
		let power:BigUint = two.clone() << (p.to_usize().unwrap()-1-1);
        let perfect_value:BigUint = power.clone() * ((power.clone()*two.clone()) -1.to_biguint().unwrap());
        save_as_file(download_filename, perfect_value.to_string())
    }
}

pub fn render(model: &crate::Model) -> seed::dom_types::Node<Msg> {
    let mut html = vec![];
    let perfects = perfects_utils::perfects().to_owned();

    for perfect in perfects.iter() {
		let perfectp:u64 = perfect.p;
		let perfect_download = perfects_utils::PerfectDownload {n: perfect.n, p: perfect.p};
		let equation:String = format!("2{} × (2{}-1)",&(perfectp-1).to_string(),&(perfectp).to_string());

        html.push(
            tr![
                td![perfect.n.to_string()],//rank
				td![El::from_html(&equation)],//perfect number as a formula

                td![perfect.digits.to_string()],//digits in length
                td![perfect.discovery],//discovery
				if model.download.n == perfect.n {
					td![perfects_utils::generate_file(model.download.n,model.download.p)]
				} else {
					td![button!["Generate",mouse_ev("mouseup", move |event| Msg::GenerateDownload(event, perfect_download))]]
				},
            ]
        );
    }

    div![
        h1!["The Perfect Numbers"],
        br![],
        br![],
        br![],
        table![
            attrs!{At::Class => "perfecttable text"},
            tbody![
                tr![
                    td![
                        b!["No."]
                    ],
                    td![
                        b!["Prime"]
                    ],
                    td![
                        b!["Digits"]
                    ],
                    td![
                        b!["Discovered"]
                    ],
                    td![
                        b!["Download"]
                    ]
                ],
                html
            ]
        ]
    ]
}

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

    #[test]
    fn perfect_test<'a>() {
        let mut perfects:Vec<perfects_utils::Perfect> = perfects_utils::perfects();
		perfects.reverse();
        assert_eq!(perfects[49].digits, 46498850);
        assert_eq!(perfects[39].digits, 12640858);
    }
}<|endoftext|>


<commit_before>use std::sync::{Arc};
use std::f64::consts::{PI};
use std::f64::{EPSILON};

use cgmath::{Point3, Vector3, InnerSpace};

use camera::{Camera};
use context::{Context};
use input::{InputFrame};

// TODO: put in a soft cap on elevation with a slow drift
//
pub struct PhysicsFrame {
	pub frame_counter:   u64,
	pub camera:          Camera,
	pub player_position: Point3<f64>,
	pub azimuth:         f64,
	pub elevation:       f64,
}

impl PhysicsFrame {
	pub fn frame_zero(aspect_ratio: f64) -> PhysicsFrame {
		let player_position = Point3::new(0f64, 1f64, 0f64);
		let azimuth   = 0f64;
		let elevation = 0f64;
		let view_direction = PhysicsFrame::view_direction(azimuth, elevation);

		PhysicsFrame {
			frame_counter:   0,
			camera:          Camera::new(player_position, view_direction, aspect_ratio),
			player_position: player_position,
			azimuth:         azimuth,
			elevation:       elevation,
		}
	}

	pub fn new(context: Arc<Context>, frame: Arc<PhysicsFrame>, input_frame: Arc<InputFrame>) -> PhysicsFrame {
		let angles_delta = -input_frame.action_state.view_direction; // TODO: scale

		let azimuth   = frame.azimuth   + angles_delta.x;
		let elevation = frame.elevation + angles_delta.y;
		let elevation = elevation.min(PI - EPSILON).max(EPSILON);
		let view_direction = PhysicsFrame::view_direction(azimuth, elevation);
		let right = view_direction.cross(Vector3::new(0f64, 1f64, 0f64)).normalize();

		let input_direction = input_frame.action_state.movement_direction; // TODO: scale

		let flat_view_direction = (Vector3 { y: 0f64, .. view_direction }).normalize();
		let flat_right          = (Vector3 { y: 0f64, ..          right }).normalize();

		// TODO: generalize and factor out all integration
		//
		const FUDGE: f64 = 0.1f64;
		let acceleration
			= flat_view_direction * input_direction.x * FUDGE
			+ flat_right          * input_direction.y * FUDGE;

		let player_position = frame.player_position + acceleration;

		// TODO: this can be kicked up in a task at the start (if we use last frame's position)
		//
		let camera = Camera::new(player_position, view_direction, context.render.aspect_ratio());

		PhysicsFrame {
			frame_counter: frame.frame_counter + 1,
			camera: camera,
			player_position: player_position,
			azimuth: azimuth,
			elevation: elevation,
		}
	}

	fn view_direction(azimuth: f64, elevation: f64) -> Vector3<f64> {
		Vector3 {
			x:  elevation.sin() * azimuth.cos(),
			y: -elevation.cos(),
			z: -elevation.sin() * azimuth.sin(),
		}
	}

	pub fn get_view_direction(&self) -> Vector3<f64> {
		PhysicsFrame::view_direction(self.azimuth, self.elevation)
	}
}
<commit_msg>Limit view elevation more sanely<commit_after>use std::sync::{Arc};
use std::f64::consts::{PI};

use cgmath::{Point3, Vector3, InnerSpace};

use camera::{Camera};
use context::{Context};
use input::{InputFrame};

// TODO: put in a soft cap on elevation with a slow drift
//
pub struct PhysicsFrame {
	pub frame_counter:   u64,
	pub camera:          Camera,
	pub player_position: Point3<f64>,
	pub azimuth:         f64,
	pub elevation:       f64,
}

impl PhysicsFrame {
	pub fn frame_zero(aspect_ratio: f64) -> PhysicsFrame {
		let player_position = Point3::new(0f64, 1f64, 0f64);
		let azimuth   = 0f64;
		let elevation = 0f64;
		let view_direction = PhysicsFrame::view_direction(azimuth, elevation);

		PhysicsFrame {
			frame_counter:   0,
			camera:          Camera::new(player_position, view_direction, aspect_ratio),
			player_position: player_position,
			azimuth:         azimuth,
			elevation:       elevation,
		}
	}

	pub fn new(context: Arc<Context>, frame: Arc<PhysicsFrame>, input_frame: Arc<InputFrame>) -> PhysicsFrame {
		const ELEVATION_LIMIT: f64 = 0.95;
		let angles_delta = -input_frame.action_state.view_direction; // TODO: scale

		let azimuth   = frame.azimuth   + angles_delta.x;
		let elevation = frame.elevation + angles_delta.y;
		let elevation = elevation.min(PI * ELEVATION_LIMIT).max(PI * (1f64 - ELEVATION_LIMIT));
		let view_direction = PhysicsFrame::view_direction(azimuth, elevation);
		let right = view_direction.cross(Vector3::new(0f64, 1f64, 0f64)).normalize();

		let input_direction = input_frame.action_state.movement_direction; // TODO: scale

		let flat_view_direction = (Vector3 { y: 0f64, .. view_direction }).normalize();
		let flat_right          = (Vector3 { y: 0f64, ..          right }).normalize();

		// TODO: generalize and factor out all integration
		//
		const FUDGE: f64 = 0.1f64;
		let acceleration
			= flat_view_direction * input_direction.x * FUDGE
			+ flat_right          * input_direction.y * FUDGE;

		let player_position = frame.player_position + acceleration;

		// TODO: this can be kicked up in a task at the start (if we use last frame's position)
		//
		let camera = Camera::new(player_position, view_direction, context.render.aspect_ratio());

		PhysicsFrame {
			frame_counter: frame.frame_counter + 1,
			camera: camera,
			player_position: player_position,
			azimuth: azimuth,
			elevation: elevation,
		}
	}

	fn view_direction(azimuth: f64, elevation: f64) -> Vector3<f64> {
		Vector3 {
			x:  elevation.sin() * azimuth.cos(),
			y: -elevation.cos(),
			z: -elevation.sin() * azimuth.sin(),
		}
	}

	pub fn get_view_direction(&self) -> Vector3<f64> {
		PhysicsFrame::view_direction(self.azimuth, self.elevation)
	}
}
<|endoftext|>


<commit_before>//! Relay for TCP server that running on the server side

use std::io::{self, ErrorKind};
use std::sync::Arc;
use std::time::Duration;

use config::{Config, ServerConfig};

use relay::boxed_future;
use relay::dns_resolver::resolve;
use relay::socks5::Address;
use relay::tcprelay::crypto_io::{DecryptedRead, EncryptedWrite};

use futures::stream::Stream;
use futures::{self, Future};

use tokio;
use tokio::net::{TcpListener, TcpStream};
use tokio_io::io::{ReadHalf, WriteHalf};
use tokio_io::{AsyncRead, IoFuture};

use super::{proxy_handshake, try_timeout, tunnel, DecryptedHalf, EncryptedHalfFut, TcpStreamConnect};

/// Context for doing handshake with client
pub struct TcpRelayClientHandshake {
    s: TcpStream,
    svr_cfg: Arc<ServerConfig>,
    config: Arc<Config>,
}

impl TcpRelayClientHandshake {
    /// Doing handshake with client
    pub fn handshake(self) -> impl Future<Item = TcpRelayClientPending, Error = io::Error> {
        let TcpRelayClientHandshake { s, svr_cfg, config } = self;

        futures::lazy(move || s.peer_addr().map(|p| (s, p))).and_then(|(s, peer_addr)| {
            debug!("Handshaking with peer {}", peer_addr);

            let timeout = *svr_cfg.timeout();
            proxy_handshake(s, svr_cfg).and_then(move |(r_fut, w_fut)| {
                r_fut.and_then(move |r| {
                                   let fut = Address::read_from(r).map_err(move |_| {
                                       io::Error::new(ErrorKind::Other,
                                       format!("failed to decode Address, may be wrong method or key, peer: {}",
                                               peer_addr))
                                   });
                                   try_timeout(fut, timeout)
                               })
                     .map(move |(r, addr)| TcpRelayClientPending { r: r,
                                                                   addr: addr,
                                                                   w: w_fut,
                                                                   timeout: timeout,
                                                                   config: config, })
            })
        })
    }
}

/// Context for connecting remote
pub struct TcpRelayClientPending {
    r: DecryptedHalf,
    addr: Address,
    w: EncryptedHalfFut,
    timeout: Option<Duration>,
    config: Arc<Config>,
}

impl TcpRelayClientPending {
    /// Connect to the remote server
    #[inline]
    fn connect_remote(config: Arc<Config>,
                      addr: Address,
                      timeout: Option<Duration>)
                      -> impl Future<Item = TcpStream, Error = io::Error> {
        debug!("Connecting to remote {}", addr);

        match addr {
            Address::SocketAddress(saddr) => {
                if config.forbidden_ip.contains(&saddr.ip()) {
                    let err = io::Error::new(ErrorKind::Other,
                                             format!("{} is forbidden, failed to connect {}", saddr.ip(), saddr));
                    return boxed_future(futures::done(Err(err)));
                }

                let conn = TcpStream::connect(&saddr);
                let fut = try_timeout(conn, timeout);
                boxed_future(fut)
            }
            Address::DomainNameAddress(dname, port) => {
                let fut = {
                    try_timeout(resolve(config, dname.as_str(), port, true), timeout).and_then(move |addrs| {
                        let conn = TcpStreamConnect::new(addrs.into_iter());
                        try_timeout(conn, timeout)
                    })
                };
                boxed_future(fut)
            }
        }
    }

    /// Connect to the remote server
    pub fn connect(self) -> impl Future<Item = TcpRelayClientConnected, Error = io::Error> + Send {
        let addr = self.addr.clone();
        let client_pair = (self.r, self.w);
        let timeout = self.timeout;
        TcpRelayClientPending::connect_remote(self.config, self.addr, self.timeout).map(move |stream| {
            TcpRelayClientConnected { server: stream.split(),
                                      client: client_pair,
                                      addr: addr,
                                      timeout: timeout, }
        })
    }
}

/// Context for extablishing tunnel
pub struct TcpRelayClientConnected {
    server: (ReadHalf<TcpStream>, WriteHalf<TcpStream>),
    client: (DecryptedHalf, EncryptedHalfFut),
    addr: Address,
    timeout: Option<Duration>,
}

impl TcpRelayClientConnected {
    /// Establish tunnel
    #[inline]
    pub fn tunnel(self) -> impl Future<Item = (), Error = io::Error> + Send {
        let (svr_r, svr_w) = self.server;
        let (r, w_fut) = self.client;
        let timeout = self.timeout;

        tunnel(self.addr,
               r.copy_timeout_opt(svr_w, self.timeout),
               w_fut.and_then(move |w| w.copy_timeout_opt(svr_r, timeout)))
    }
}

fn handle_client(server_cfg: Arc<ServerConfig>,
                 config: Arc<Config>,
                 socket: TcpStream)
                 -> impl Future<Item = (), Error = ()> + Send {
    futures::lazy(move || match socket.peer_addr() {
                      Ok(addr) => Ok((socket, addr)),
                      Err(err) => {
                          error!("Failed to get peer_addr after accept: {}", err);
                          Err(())
                      }
                  }).and_then(move |(socket, addr)| {
                                      trace!("Got connection, addr: {}", addr);
                                      trace!("Picked proxy server: {:?}", server_cfg);

                                      let client = TcpRelayClientHandshake { s: socket,
                                                                             svr_cfg: server_cfg,
                                                                             config: config, };

                                      client.handshake()
                                            .and_then(|c| c.connect())
                                            .and_then(|c| c.tunnel())
                                            .map_err(move |err| {
                                                         error!("Failed to handle client ({}): {}", addr, err);
                                                     })
                                  })
}

/// Runs the server
pub fn run(config: Arc<Config>) -> impl Future<Item = (), Error = io::Error> + Send {
    let mut fut: Option<IoFuture<()>> = None;

    for svr_cfg in &config.server {
        let listener = {
            let addr = svr_cfg.addr();
            let addr = addr.listen_addr();

            let listener = TcpListener::bind(&addr).unwrap_or_else(|err| panic!("Failed to listen, {}", err));

            info!("ShadowSocks TCP Listening on {}", addr);
            listener
        };

        let svr_cfg = Arc::new(svr_cfg.clone());
        let config = config.clone();
        let listening = listener.incoming()
                                .for_each(move |socket| {
                                              let server_cfg = svr_cfg.clone();
                                              let config = config.clone();
                                              tokio::spawn(handle_client(server_cfg, config, socket));
                                              Ok(())
                                          })
                                .map_err(|err| {
                                             error!("Server run failed: {}", err);
                                             err
                                         });

        fut = Some(match fut.take() {
                       Some(fut) => Box::new(fut.join(listening).map(|_| ())) as IoFuture<()>,
                       None => Box::new(listening) as IoFuture<()>,
                   })
    }

    fut.expect("Must have at least one server")
}
<commit_msg>Optimize server listening logic, join_all<commit_after>//! Relay for TCP server that running on the server side

use std::io::{self, ErrorKind};
use std::sync::Arc;
use std::time::Duration;

use config::{Config, ServerConfig};

use relay::boxed_future;
use relay::dns_resolver::resolve;
use relay::socks5::Address;
use relay::tcprelay::crypto_io::{DecryptedRead, EncryptedWrite};

use futures::future::join_all;
use futures::stream::Stream;
use futures::{self, Future};

use tokio;
use tokio::net::{TcpListener, TcpStream};
use tokio_io::io::{ReadHalf, WriteHalf};
use tokio_io::AsyncRead;

use super::{proxy_handshake, try_timeout, tunnel, DecryptedHalf, EncryptedHalfFut, TcpStreamConnect};

/// Context for doing handshake with client
pub struct TcpRelayClientHandshake {
    s: TcpStream,
    svr_cfg: Arc<ServerConfig>,
    config: Arc<Config>,
}

impl TcpRelayClientHandshake {
    /// Doing handshake with client
    pub fn handshake(self) -> impl Future<Item = TcpRelayClientPending, Error = io::Error> {
        let TcpRelayClientHandshake { s, svr_cfg, config } = self;

        futures::lazy(move || s.peer_addr().map(|p| (s, p))).and_then(|(s, peer_addr)| {
            debug!("Handshaking with peer {}", peer_addr);

            let timeout = *svr_cfg.timeout();
            proxy_handshake(s, svr_cfg).and_then(move |(r_fut, w_fut)| {
                r_fut.and_then(move |r| {
                                   let fut = Address::read_from(r).map_err(move |_| {
                                       io::Error::new(ErrorKind::Other,
                                       format!("failed to decode Address, may be wrong method or key, peer: {}",
                                               peer_addr))
                                   });
                                   try_timeout(fut, timeout)
                               })
                     .map(move |(r, addr)| TcpRelayClientPending { r: r,
                                                                   addr: addr,
                                                                   w: w_fut,
                                                                   timeout: timeout,
                                                                   config: config, })
            })
        })
    }
}

/// Context for connecting remote
pub struct TcpRelayClientPending {
    r: DecryptedHalf,
    addr: Address,
    w: EncryptedHalfFut,
    timeout: Option<Duration>,
    config: Arc<Config>,
}

impl TcpRelayClientPending {
    /// Connect to the remote server
    #[inline]
    fn connect_remote(config: Arc<Config>,
                      addr: Address,
                      timeout: Option<Duration>)
                      -> impl Future<Item = TcpStream, Error = io::Error> {
        debug!("Connecting to remote {}", addr);

        match addr {
            Address::SocketAddress(saddr) => {
                if config.forbidden_ip.contains(&saddr.ip()) {
                    let err = io::Error::new(ErrorKind::Other,
                                             format!("{} is forbidden, failed to connect {}", saddr.ip(), saddr));
                    return boxed_future(futures::done(Err(err)));
                }

                let conn = TcpStream::connect(&saddr);
                let fut = try_timeout(conn, timeout);
                boxed_future(fut)
            }
            Address::DomainNameAddress(dname, port) => {
                let fut = {
                    try_timeout(resolve(config, dname.as_str(), port, true), timeout).and_then(move |addrs| {
                        let conn = TcpStreamConnect::new(addrs.into_iter());
                        try_timeout(conn, timeout)
                    })
                };
                boxed_future(fut)
            }
        }
    }

    /// Connect to the remote server
    pub fn connect(self) -> impl Future<Item = TcpRelayClientConnected, Error = io::Error> + Send {
        let addr = self.addr.clone();
        let client_pair = (self.r, self.w);
        let timeout = self.timeout;
        TcpRelayClientPending::connect_remote(self.config, self.addr, self.timeout).map(move |stream| {
            TcpRelayClientConnected { server: stream.split(),
                                      client: client_pair,
                                      addr: addr,
                                      timeout: timeout, }
        })
    }
}

/// Context for extablishing tunnel
pub struct TcpRelayClientConnected {
    server: (ReadHalf<TcpStream>, WriteHalf<TcpStream>),
    client: (DecryptedHalf, EncryptedHalfFut),
    addr: Address,
    timeout: Option<Duration>,
}

impl TcpRelayClientConnected {
    /// Establish tunnel
    #[inline]
    pub fn tunnel(self) -> impl Future<Item = (), Error = io::Error> + Send {
        let (svr_r, svr_w) = self.server;
        let (r, w_fut) = self.client;
        let timeout = self.timeout;

        tunnel(self.addr,
               r.copy_timeout_opt(svr_w, self.timeout),
               w_fut.and_then(move |w| w.copy_timeout_opt(svr_r, timeout)))
    }
}

fn handle_client(server_cfg: Arc<ServerConfig>,
                 config: Arc<Config>,
                 socket: TcpStream)
                 -> impl Future<Item = (), Error = ()> + Send {
    futures::lazy(move || match socket.peer_addr() {
                      Ok(addr) => Ok((socket, addr)),
                      Err(err) => {
                          error!("Failed to get peer_addr after accept: {}", err);
                          Err(())
                      }
                  }).and_then(move |(socket, addr)| {
                                      trace!("Got connection, addr: {}", addr);
                                      trace!("Picked proxy server: {:?}", server_cfg);

                                      let client = TcpRelayClientHandshake { s: socket,
                                                                             svr_cfg: server_cfg,
                                                                             config: config, };

                                      client.handshake()
                                            .and_then(|c| c.connect())
                                            .and_then(|c| c.tunnel())
                                            .map_err(move |err| {
                                                         error!("Failed to handle client ({}): {}", addr, err);
                                                     })
                                  })
}

/// Runs the server
pub fn run(config: Arc<Config>) -> impl Future<Item = (), Error = io::Error> + Send {
    let mut vec_fut = Vec::with_capacity(config.server.len());

    for svr_cfg in &config.server {
        let listener = {
            let addr = svr_cfg.addr();
            let addr = addr.listen_addr();

            let listener = TcpListener::bind(&addr).unwrap_or_else(|err| panic!("Failed to listen, {}", err));

            info!("ShadowSocks TCP Listening on {}", addr);
            listener
        };

        let svr_cfg = Arc::new(svr_cfg.clone());
        let config = config.clone();
        let listening = listener.incoming()
                                .for_each(move |socket| {
                                              let server_cfg = svr_cfg.clone();
                                              let config = config.clone();
                                              tokio::spawn(handle_client(server_cfg, config, socket));
                                              Ok(())
                                          })
                                .map_err(|err| {
                                             error!("Server run failed: {}", err);
                                             err
                                         });

        vec_fut.push(boxed_future(listening));
    }

    join_all(vec_fut).map(|_| ())
}
<|endoftext|>


<commit_before>// SPDX-License-Identifier: MIT
// Copyright (C) 2018-present iced project and contributors

// This requires Rust 1.54.0 or later. The double cfg_attr is required so older versions can compile it.
#![cfg_attr(doc, cfg_attr(doc, doc = include_str!("../README.md")))]
#![cfg_attr(not(doc), doc = "Run cargo doc to see the docs (needs Rust 1.54.0 or later)")]
#![doc(html_logo_url = "https://raw.githubusercontent.com/icedland/iced/master/logo.png")]
#![doc(html_root_url = "https://docs.rs/iced-x86/1.15.0")]
#![allow(unknown_lints)]
#![warn(absolute_paths_not_starting_with_crate)]
#![warn(anonymous_parameters)]
#![warn(elided_lifetimes_in_paths)]
#![warn(explicit_outlives_requirements)]
#![warn(invalid_html_tags)]
#![warn(keyword_idents)]
#![warn(meta_variable_misuse)]
#![warn(missing_copy_implementations)]
#![warn(missing_debug_implementations)]
#![warn(missing_docs)]
#![warn(non_ascii_idents)]
#![warn(trivial_casts)]
#![warn(trivial_numeric_casts)]
#![warn(unused_extern_crates)]
#![warn(unused_import_braces)]
#![warn(unused_lifetimes)]
#![warn(unused_must_use)]
#![warn(unused_qualifications)]
#![warn(unused_results)]
#![allow(clippy::bool_assert_comparison)]
#![allow(clippy::branches_sharing_code)]
#![allow(clippy::cast_lossless)]
#![allow(clippy::collapsible_else_if)]
#![allow(clippy::collapsible_if)]
#![allow(clippy::field_reassign_with_default)]
#![allow(clippy::manual_range_contains)]
#![allow(clippy::match_ref_pats)]
#![allow(clippy::ptr_eq)]
#![allow(clippy::too_many_arguments)]
#![allow(clippy::type_complexity)]
#![allow(clippy::upper_case_acronyms)]
#![allow(clippy::wrong_self_convention)]
#![warn(clippy::cloned_instead_of_copied)]
#![warn(clippy::dbg_macro)]
#![warn(clippy::debug_assert_with_mut_call)]
#![warn(clippy::default_trait_access)]
#![warn(clippy::doc_markdown)]
#![warn(clippy::empty_line_after_outer_attr)]
#![warn(clippy::explicit_into_iter_loop)]
#![warn(clippy::explicit_iter_loop)]
#![warn(clippy::fallible_impl_from)]
#![warn(clippy::get_unwrap)]
#![warn(clippy::implicit_saturating_sub)]
#![warn(clippy::large_digit_groups)]
#![warn(clippy::let_unit_value)]
#![warn(clippy::match_bool)]
#![warn(clippy::match_on_vec_items)]
#![warn(clippy::match_wild_err_arm)]
#![warn(clippy::missing_errors_doc)]
#![warn(clippy::missing_inline_in_public_items)]
#![warn(clippy::must_use_candidate)]
#![warn(clippy::needless_borrow)]
#![warn(clippy::print_stderr)]
#![warn(clippy::print_stdout)]
#![warn(clippy::rc_buffer)]
#![warn(clippy::redundant_closure)]
#![warn(clippy::redundant_closure_for_method_calls)]
#![warn(clippy::same_functions_in_if_condition)]
#![warn(clippy::todo)]
#![warn(clippy::unimplemented)]
#![warn(clippy::unreadable_literal)]
#![warn(clippy::unused_self)]
#![warn(clippy::unwrap_in_result)]
#![warn(clippy::used_underscore_binding)]
#![warn(clippy::useless_let_if_seq)]
#![warn(clippy::useless_transmute)]
#![warn(clippy::zero_sized_map_values)]
#![cfg_attr(not(test), warn(clippy::expect_used))]
#![cfg_attr(not(test), warn(clippy::unwrap_used))]
#![cfg_attr(not(feature = "std"), no_std)]
#![doc(test(attr(deny(warnings))))]

// This should be the only place in the source code that uses no_std
#[cfg(all(feature = "std", feature = "no_std"))]
compile_error!("`std` and `no_std` features can't be used at the same time");
#[cfg(all(not(feature = "std"), not(feature = "no_std")))]
compile_error!("`std` or `no_std` feature must be defined");

#[cfg_attr(
	any(
		feature = "encoder",
		feature = "block_encoder",
		feature = "op_code_info",
		feature = "gas",
		feature = "intel",
		feature = "masm",
		feature = "nasm",
		feature = "fast_fmt"
	),
	macro_use
)]
extern crate alloc;
#[cfg(feature = "std")]
extern crate core;
#[cfg(feature = "serde")]
extern crate serde_crate as serde;

#[macro_use]
mod iced_assert {
	macro_rules! iced_assert {
		($($expr:tt)*) => {{
			// If it's a debug build, include the expression string
			#[cfg(debug_assertions)]
			{
				assert!($($expr)*);
			}

			// If it's not a debug build, don't include the expression string
			#[cfg(not(debug_assertions))]
			{
				if !($($expr)*) {
					panic!();
				}
			}
		}};
	}
}

#[cfg(all(feature = "encoder", feature = "block_encoder"))]
mod block_enc;
mod code;
#[cfg(feature = "code_asm")]
pub mod code_asm;
#[cfg(any(feature = "decoder", feature = "encoder"))]
mod constant_offsets;
#[cfg(any(feature = "decoder", feature = "gas", feature = "intel", feature = "masm", feature = "nasm", feature = "fast_fmt"))]
mod data_reader;
#[cfg(feature = "decoder")]
mod decoder;
#[cfg(feature = "encoder")]
mod encoder;
mod enums;
#[cfg(any(feature = "gas", feature = "intel", feature = "masm", feature = "nasm", feature = "fast_fmt"))]
mod formatter;
pub(crate) mod iced_constants;
mod iced_error;
mod iced_features;
#[cfg(feature = "instr_info")]
mod info;
mod instruction;
#[cfg(feature = "encoder")]
mod instruction_create;
mod instruction_internal;
mod instruction_memory_sizes;
mod instruction_op_counts;
mod memory_size;
mod mnemonic;
mod mnemonics;
#[cfg(feature = "mvex")]
mod mvex;
mod register;
#[cfg(test)]
pub(crate) mod test;
#[cfg(test)]
pub(crate) mod test_utils;
#[cfg(any(feature = "decoder", feature = "encoder"))]
mod tuple_type_tbl;

#[cfg(all(feature = "encoder", feature = "block_encoder"))]
pub use crate::block_enc::*;
pub use crate::code::*;
#[cfg(any(feature = "decoder", feature = "encoder"))]
pub use crate::constant_offsets::*;
#[cfg(feature = "decoder")]
pub use crate::decoder::*;
#[cfg(feature = "encoder")]
pub use crate::encoder::*;
pub use crate::enums::*;
#[cfg(any(feature = "gas", feature = "intel", feature = "masm", feature = "nasm", feature = "fast_fmt"))]
pub use crate::formatter::*;
pub use crate::iced_error::*;
pub use crate::iced_features::*;
#[cfg(feature = "instr_info")]
pub use crate::info::*;
pub use crate::instruction::*;
pub use crate::memory_size::*;
pub use crate::mnemonic::*;
pub use crate::register::*;
<commit_msg>Disable buggy clippy lint<commit_after>// SPDX-License-Identifier: MIT
// Copyright (C) 2018-present iced project and contributors

// This requires Rust 1.54.0 or later. The double cfg_attr is required so older versions can compile it.
#![cfg_attr(doc, cfg_attr(doc, doc = include_str!("../README.md")))]
#![cfg_attr(not(doc), doc = "Run cargo doc to see the docs (needs Rust 1.54.0 or later)")]
#![doc(html_logo_url = "https://raw.githubusercontent.com/icedland/iced/master/logo.png")]
#![doc(html_root_url = "https://docs.rs/iced-x86/1.15.0")]
#![allow(unknown_lints)]
#![warn(absolute_paths_not_starting_with_crate)]
#![warn(anonymous_parameters)]
#![warn(elided_lifetimes_in_paths)]
#![warn(explicit_outlives_requirements)]
#![warn(invalid_html_tags)]
#![warn(keyword_idents)]
#![warn(meta_variable_misuse)]
#![warn(missing_copy_implementations)]
#![warn(missing_debug_implementations)]
#![warn(missing_docs)]
#![warn(non_ascii_idents)]
#![warn(trivial_casts)]
#![warn(trivial_numeric_casts)]
#![warn(unused_extern_crates)]
#![warn(unused_import_braces)]
#![warn(unused_lifetimes)]
#![warn(unused_must_use)]
#![warn(unused_qualifications)]
#![warn(unused_results)]
#![allow(clippy::bool_assert_comparison)]
#![allow(clippy::branches_sharing_code)]
#![allow(clippy::cast_lossless)]
#![allow(clippy::collapsible_else_if)]
#![allow(clippy::collapsible_if)]
#![allow(clippy::field_reassign_with_default)]
#![allow(clippy::manual_range_contains)]
#![allow(clippy::match_ref_pats)]
#![allow(clippy::ptr_eq)]
#![allow(clippy::redundant_closure)] // Clippy is buggy
#![allow(clippy::too_many_arguments)]
#![allow(clippy::type_complexity)]
#![allow(clippy::upper_case_acronyms)]
#![allow(clippy::wrong_self_convention)]
#![warn(clippy::cloned_instead_of_copied)]
#![warn(clippy::dbg_macro)]
#![warn(clippy::debug_assert_with_mut_call)]
#![warn(clippy::default_trait_access)]
#![warn(clippy::doc_markdown)]
#![warn(clippy::empty_line_after_outer_attr)]
#![warn(clippy::explicit_into_iter_loop)]
#![warn(clippy::explicit_iter_loop)]
#![warn(clippy::fallible_impl_from)]
#![warn(clippy::get_unwrap)]
#![warn(clippy::implicit_saturating_sub)]
#![warn(clippy::large_digit_groups)]
#![warn(clippy::let_unit_value)]
#![warn(clippy::match_bool)]
#![warn(clippy::match_on_vec_items)]
#![warn(clippy::match_wild_err_arm)]
#![warn(clippy::missing_errors_doc)]
#![warn(clippy::missing_inline_in_public_items)]
#![warn(clippy::must_use_candidate)]
#![warn(clippy::needless_borrow)]
#![warn(clippy::print_stderr)]
#![warn(clippy::print_stdout)]
#![warn(clippy::rc_buffer)]
#![warn(clippy::redundant_closure_for_method_calls)]
#![warn(clippy::same_functions_in_if_condition)]
#![warn(clippy::todo)]
#![warn(clippy::unimplemented)]
#![warn(clippy::unreadable_literal)]
#![warn(clippy::unused_self)]
#![warn(clippy::unwrap_in_result)]
#![warn(clippy::used_underscore_binding)]
#![warn(clippy::useless_let_if_seq)]
#![warn(clippy::useless_transmute)]
#![warn(clippy::zero_sized_map_values)]
#![cfg_attr(not(test), warn(clippy::expect_used))]
#![cfg_attr(not(test), warn(clippy::unwrap_used))]
#![cfg_attr(not(feature = "std"), no_std)]
#![doc(test(attr(deny(warnings))))]

// This should be the only place in the source code that uses no_std
#[cfg(all(feature = "std", feature = "no_std"))]
compile_error!("`std` and `no_std` features can't be used at the same time");
#[cfg(all(not(feature = "std"), not(feature = "no_std")))]
compile_error!("`std` or `no_std` feature must be defined");

#[cfg_attr(
	any(
		feature = "encoder",
		feature = "block_encoder",
		feature = "op_code_info",
		feature = "gas",
		feature = "intel",
		feature = "masm",
		feature = "nasm",
		feature = "fast_fmt"
	),
	macro_use
)]
extern crate alloc;
#[cfg(feature = "std")]
extern crate core;
#[cfg(feature = "serde")]
extern crate serde_crate as serde;

#[macro_use]
mod iced_assert {
	macro_rules! iced_assert {
		($($expr:tt)*) => {{
			// If it's a debug build, include the expression string
			#[cfg(debug_assertions)]
			{
				assert!($($expr)*);
			}

			// If it's not a debug build, don't include the expression string
			#[cfg(not(debug_assertions))]
			{
				if !($($expr)*) {
					panic!();
				}
			}
		}};
	}
}

#[cfg(all(feature = "encoder", feature = "block_encoder"))]
mod block_enc;
mod code;
#[cfg(feature = "code_asm")]
pub mod code_asm;
#[cfg(any(feature = "decoder", feature = "encoder"))]
mod constant_offsets;
#[cfg(any(feature = "decoder", feature = "gas", feature = "intel", feature = "masm", feature = "nasm", feature = "fast_fmt"))]
mod data_reader;
#[cfg(feature = "decoder")]
mod decoder;
#[cfg(feature = "encoder")]
mod encoder;
mod enums;
#[cfg(any(feature = "gas", feature = "intel", feature = "masm", feature = "nasm", feature = "fast_fmt"))]
mod formatter;
pub(crate) mod iced_constants;
mod iced_error;
mod iced_features;
#[cfg(feature = "instr_info")]
mod info;
mod instruction;
#[cfg(feature = "encoder")]
mod instruction_create;
mod instruction_internal;
mod instruction_memory_sizes;
mod instruction_op_counts;
mod memory_size;
mod mnemonic;
mod mnemonics;
#[cfg(feature = "mvex")]
mod mvex;
mod register;
#[cfg(test)]
pub(crate) mod test;
#[cfg(test)]
pub(crate) mod test_utils;
#[cfg(any(feature = "decoder", feature = "encoder"))]
mod tuple_type_tbl;

#[cfg(all(feature = "encoder", feature = "block_encoder"))]
pub use crate::block_enc::*;
pub use crate::code::*;
#[cfg(any(feature = "decoder", feature = "encoder"))]
pub use crate::constant_offsets::*;
#[cfg(feature = "decoder")]
pub use crate::decoder::*;
#[cfg(feature = "encoder")]
pub use crate::encoder::*;
pub use crate::enums::*;
#[cfg(any(feature = "gas", feature = "intel", feature = "masm", feature = "nasm", feature = "fast_fmt"))]
pub use crate::formatter::*;
pub use crate::iced_error::*;
pub use crate::iced_features::*;
#[cfg(feature = "instr_info")]
pub use crate::info::*;
pub use crate::instruction::*;
pub use crate::memory_size::*;
pub use crate::mnemonic::*;
pub use crate::register::*;
<|endoftext|>


<commit_before>

pub trait StaticSymbolTable<'a>
{
	fn lookup_name(name: &str) -> Vec<Symbol<'a>>;
	fn lookup_namespace(namespace: &str) -> Vec<Symbol<'a>>;
	fn lookup_variable(namespace: &str, name: &str) -> Vec<Symbol<'a>>;

	fn add(symbol: Symbol<'a>);
}

pub enum SymbolLocation<'a>
{
	Register { name: &'a str },
	Memory { address: MemoryAddress<'a> },
	Structured
}

pub enum SymbolClass
{
	Variable,
	Function,
	/// Includes class, enum, and interface
	Structure { subtype: String },
}

pub struct Symbol<'a>
{
	/// Namespace of this symbol, without the final "." or the name of this symbol
	pub namespace: &'a str,

	/// Identifier for the symbol (e.g. name of variable, function, class, etc. without it's namespace)
	pub name: &'a str,

	/// What this symbol represents (class, enum, variable, function, etc)
	pub symbol_class: SymbolClass,

	/// Type can be the return type of a method, the type of a variable, or None if it has no type (for instance if it is a class, enum, etc).
	pub symbol_type: Option<&'a str>,

	/// Memory location of this symbol. Methods will always map to a SymbolLocation::Memory label with a 0 offset
	pub location: SymbolLocation<'a>,
}

pub struct MemoryAddress<'a>
{
	/// Label marking the base address where the symbol is stored
	pub label_name: &'a str,

	/// Offset from the base address to access the symbol. Methods will always have an offset of 0
	pub offset: u16,
}
<commit_msg>Structure & document Symbol Table<commit_after>

pub trait StaticSymbolTable<'a>
{
	/// Return all symbols in this table with the specified name (in any namespace)
	fn lookup_name(name: &str) -> Vec<Symbol<'a>>;

	/// Return all symbols in this table with the specified namespace
	fn lookup_namespace(namespace: &str) -> Vec<Symbol<'a>>;

	/// Lookup a symbol by its name and namespace. Duplicate symbols are not allowed, so the result will be unique
	fn lookup_variable(namespace: &str, name: &str) -> Symbol<'a>;

	/// Lookup a symbol by its name and namespace. Duplicate symbols are not allowed, so the result will be unique
	fn lookup_function(namespace: &str, name: &str, argument_types: &Vec<&str>) -> Symbol<'a>;

	/// Adds a symbol to this table and allocates it's location
	/// Returns true if the symbol could be added; false otherwise
	/// Duplicate symbols are not allowed
	/// TODO: support overloaded methods
	fn add(class: SymbolClass<'a>, namespace: &'a str, name: &'a str) -> bool;
}

pub enum SymbolLocation<'a>
{
	/// Indicates that a register has been reserved for a specific use (e.g. by a variable)
	Register { name: &'a str },

	/// Indicates a location in memory
	Memory { address: MemoryAddress<'a> },

	/// Indicates that the symbol should not be accessed, as it represents a structured entity
	Structured
}

pub enum SymbolClass<'a>
{
	Variable { variable_type: &'a str },

	/// Function signature //TODO: support exceptions
	Function { return_type: &'a str, argument_types: &'a Vec<&'a str> },

	/// Includes class, enum, and interface
	Structure { subtype: &'a str },
}

pub struct Symbol<'a>
{
	/// Namespace of this symbol, without the final "." or the name of this symbol
	pub namespace: &'a str,

	/// Identifier for the symbol (e.g. name of variable, function, class, etc. without it's namespace)
	pub name: &'a str,

	/// What this symbol represents (class, enum, variable, function, etc)
	pub symbol_class: SymbolClass<'a>,

	/// Memory location of this symbol. Methods will always map to a SymbolLocation::Memory label with a 0 offset
	pub location: SymbolLocation<'a>,
}

pub struct MemoryAddress<'a>
{
	/// Label marking the base address where the symbol is stored
	pub label_name: &'a str,

	/// Offset from the base address to access the symbol. Methods will always have an offset of 0
	pub offset: u16,
}
<|endoftext|>


<commit_before>use cgmath::*;
use serde::{Deserialize, Serialize};

use std::collections::VecDeque;

use crate::terrain::tile_cache::Priority;

use crate::utils::math::BoundingBox;

const ROOT_SIDE_LENGTH: f32 = 4194304.0;

lazy_static! {
    pub static ref OFFSETS: [Vector2<i32>; 4] =
        [Vector2::new(0, 0), Vector2::new(1, 0), Vector2::new(0, 1), Vector2::new(1, 1),];
    pub static ref CENTER_OFFSETS: [Vector2<i32>; 4] =
        [Vector2::new(-1, -1), Vector2::new(1, -1), Vector2::new(-1, 1), Vector2::new(1, 1),];
}

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Serialize, Deserialize)]
pub(crate) struct VNode {
    level: u8,
    x: u32,
    y: u32,
}
impl VNode {
    pub fn root() -> Self {
        Self { level: 0, x: 0, y: 0 }
    }

    pub fn level(&self) -> u8 {
        self.level
    }

    pub fn side_length(&self) -> f32 {
        ROOT_SIDE_LENGTH / (1u32 << self.level) as f32
    }
    pub fn min_distance(&self) -> f32 {
        self.side_length() * 1.95
    }

    pub fn bounds(&self) -> BoundingBox {
        let side_length = self.side_length();
        let min = Point3::new(
            -ROOT_SIDE_LENGTH * 0.5 + side_length * self.x as f32,
            0.0,
            -ROOT_SIDE_LENGTH * 0.5 + side_length * self.y as f32,
        );
        let max = Point3::new(min.x + side_length, 8000.0, min.z + side_length);
        BoundingBox { min, max }
    }

    /// How much this node is needed for the current frame. Nodes with priority less than 1.0 will
    /// not be rendered (they are too detailed).
    pub fn priority(&self, camera: Point3<f32>) -> Priority {
        let min_distance = self.min_distance();
        Priority::from_f32(
            (min_distance * min_distance) / self.bounds().square_distance_xz(camera).max(0.001),
        )
    }

    pub fn parent(&self) -> Option<(VNode, u8)> {
        if self.level == 0 {
            return None;
        }
        let child_index = ((self.x % 2) + (self.y % 2) * 2) as u8;
        Some((VNode { level: self.level - 1, x: self.x / 2, y: self.y / 2 }, child_index))
    }

    pub fn children(&self) -> [VNode; 4] {
        assert!(self.level < 31);
        [
            VNode { level: self.level + 1, x: self.x * 2, y: self.y * 2 },
            VNode { level: self.level + 1, x: self.x * 2 + 1, y: self.y * 2 },
            VNode { level: self.level + 1, x: self.x * 2, y: self.y * 2 + 1 },
            VNode { level: self.level + 1, x: self.x * 2 + 1, y: self.y * 2 + 1 },
        ]
    }

    pub fn find_ancestor<Visit>(&self, mut visit: Visit) -> Option<(VNode, usize, Vector2<u32>)>
    where
        Visit: FnMut(VNode) -> bool,
    {
        let mut node = *self;
        let mut generations = 0;
        let mut offset = Vector2::new(0, 0);
        while !visit(node) {
            if node.level == 0 {
                return None;
            }
            offset += Vector2::new(node.x & 1, node.y & 1) * (1 << generations);
            generations += 1;
            node = VNode { level: node.level - 1, x: node.x / 2, y: node.y / 2 };
        }
        Some((node, generations, offset))
    }

    pub fn breadth_first<Visit>(mut visit: Visit)
    where
        Visit: FnMut(VNode) -> bool,
    {
        let mut pending = VecDeque::new();
        if visit(VNode::root()) {
            pending.push_back(VNode::root());
        }
        while let Some(node) = pending.pop_front() {
            for &child in node.children().iter() {
                if visit(child) {
                    pending.push_back(child);
                }
            }
        }
    }

    pub fn make_nodes(playable_radius: f32, max_level: u8) -> Vec<VNode> {
        let mut nodes = vec![Self::root()];
        let mut pending = VecDeque::new();
        pending.push_back(Self::root());

        while let Some(parent) = pending.pop_front() {
            if parent.level >= max_level {
                continue;
            }

            for &child in parent.children().iter() {
                if child.bounds().distance(Point3::origin())
                    < playable_radius + child.min_distance()
                {
                    nodes.push(child);
                    pending.push_back(child);
                }
            }
        }

        nodes
    }
}
<commit_msg>Pack VNode into a u64<commit_after>use cgmath::*;
use serde::{Deserialize, Serialize};

use std::collections::VecDeque;

use crate::terrain::tile_cache::Priority;

use crate::utils::math::BoundingBox;

const ROOT_SIDE_LENGTH: f32 = 4194304.0;

lazy_static! {
    pub static ref OFFSETS: [Vector2<i32>; 4] =
        [Vector2::new(0, 0), Vector2::new(1, 0), Vector2::new(0, 1), Vector2::new(1, 1),];
    pub static ref CENTER_OFFSETS: [Vector2<i32>; 4] =
        [Vector2::new(-1, -1), Vector2::new(1, -1), Vector2::new(-1, 1), Vector2::new(1, 1),];
}

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Serialize, Deserialize)]
pub(crate) struct VNode(u64);

impl VNode {
    fn new(level: u8, x: u32, y: u32) -> Self {
        Self((level as u64) << 56 | (y as u64) << 24 | (x as u64))
    }
    fn x(&self) -> u32 {
        self.0 as u32 & 0xffffff
    }
    fn y(&self) -> u32 {
        (self.0 >> 24) as u32 & 0xffffff

    }
    pub fn level(&self) -> u8 {
        (self.0 >> 56) as u8
    }

    pub fn root() -> Self {
        Self::new(0, 0, 0)
    }

    pub fn side_length(&self) -> f32 {
        ROOT_SIDE_LENGTH / (1u32 << self.level()) as f32
    }
    pub fn min_distance(&self) -> f32 {
        self.side_length() * 1.95
    }

    pub fn bounds(&self) -> BoundingBox {
        let side_length = self.side_length();
        let min = Point3::new(
            -ROOT_SIDE_LENGTH * 0.5 + side_length * self.x() as f32,
            0.0,
            -ROOT_SIDE_LENGTH * 0.5 + side_length * self.y() as f32,
        );
        let max = Point3::new(min.x + side_length, 8000.0, min.z + side_length);
        BoundingBox { min, max }
    }

    /// How much this node is needed for the current frame. Nodes with priority less than 1.0 will
    /// not be rendered (they are too detailed).
    pub fn priority(&self, camera: Point3<f32>) -> Priority {
        let min_distance = self.min_distance();
        Priority::from_f32(
            (min_distance * min_distance) / self.bounds().square_distance_xz(camera).max(0.001),
        )
    }

    pub fn parent(&self) -> Option<(VNode, u8)> {
        if self.level() == 0 {
            return None;
        }
        let child_index = ((self.x() % 2) + (self.y() % 2) * 2) as u8;
        Some((VNode::new(self.level() - 1, self.x() / 2, self.y() / 2), child_index))
    }

    pub fn children(&self) -> [VNode; 4] {
        assert!(self.level() < 31);
        [
            VNode::new(self.level() + 1, self.x() * 2, self.y() * 2),
            VNode::new(self.level() + 1, self.x() * 2+1, self.y() * 2),
            VNode::new(self.level() + 1, self.x() * 2, self.y() * 2+1),
            VNode::new(self.level() + 1, self.x() * 2+1, self.y() * 2+1),
        ]
    }

    pub fn find_ancestor<Visit>(&self, mut visit: Visit) -> Option<(VNode, usize, Vector2<u32>)>
    where
        Visit: FnMut(VNode) -> bool,
    {
        let mut node = *self;
        let mut generations = 0;
        let mut offset = Vector2::new(0, 0);
        while !visit(node) {
            if node.level() == 0 {
                return None;
            }
            offset += Vector2::new(node.x() & 1, node.y() & 1) * (1 << generations);
            generations += 1;
            node = VNode::new(node.level() - 1, node.x() / 2, node.y() / 2);
        }
        Some((node, generations, offset))
    }

    pub fn breadth_first<Visit>(mut visit: Visit)
    where
        Visit: FnMut(VNode) -> bool,
    {
        let mut pending = VecDeque::new();
        if visit(VNode::root()) {
            pending.push_back(VNode::root());
        }
        while let Some(node) = pending.pop_front() {
            for &child in node.children().iter() {
                if visit(child) {
                    pending.push_back(child);
                }
            }
        }
    }

    pub fn make_nodes(playable_radius: f32, max_level: u8) -> Vec<VNode> {
        let mut nodes = vec![Self::root()];
        let mut pending = VecDeque::new();
        pending.push_back(Self::root());

        while let Some(parent) = pending.pop_front() {
            if parent.level() >= max_level {
                continue;
            }

            for &child in parent.children().iter() {
                if child.bounds().distance(Point3::origin())
                    < playable_radius + child.min_distance()
                {
                    nodes.push(child);
                    pending.push_back(child);
                }
            }
        }

        nodes
    }
}
<|endoftext|>


<commit_before>//
// gash.rs
//
// Starting code for PS2
// Running on Rust 0.9
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu, David Evans
// Version 0.4
//
/*
Vikram Bhasin vb8nd and Justin Ingram jci5kb
*/

extern mod extra;

use std::{io, run, os};
use std::io::buffered::BufferedReader;
use std::io::stdin;
use std::os::getcwd;
use extra::getopts;
use std::run::Process;
use std::run::ProcessOutput;
use std::run::ProcessOptions;
use std::option::{Option, None, Some};

struct Shell {
    cmd_prompt: ~str,
    //vector
}

impl Shell {
    fn new(prompt_str: &str) -> Shell {
        Shell {
            cmd_prompt: prompt_str.to_owned(),
        }
    }

    fn run(&mut self) {
        let mut stdin = BufferedReader::new(stdin());

        loop {
            print(self.cmd_prompt);
            io::stdio::flush();

            let line = stdin.read_line().unwrap();
            let cmd_line = line.trim().to_owned();
            let program = cmd_line.splitn(' ', 1).nth(0).expect("no program");

            match program {
                ""      =>  { continue; }
                "exit"  =>  { return; }
                "cd"	=>  { self.changeDir(cmd_line); }
                "history" =>{ self.history(cmd_line); }
                _       =>  { self.run_cmdline(cmd_line); }
            }
        }
    }

    fn run_cmdline(&mut self, cmd_line: &str) {
        let mut argv: ~[~str] =
            cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();

        if argv.len() > 0 {
            let program: ~str = argv.remove(0);

            //Let's process the argv

            let endopt = argv.pop_opt();
            let end = match endopt {
		Some(stringy) => { stringy }
		None => { ~"" }
            };

            if end.eq(&~"&") {
		println("Start in a new process" + end);
            } else {
		println("No new process");
		if !end.eq(&~"") {
		    argv.push(end.to_owned());
		}
            }

            self.run_cmd(program, argv);
        }
    }

    fn run_cmd(&mut self, program: &str, argv: &[~str]) {
        if self.cmd_exists(program) {
	    // Old stuff
            run::process_status(program, argv);

            //println("Run command hit");
            //println(program);
            /*
            let mut whichprocop = ProcessOptions::new();
	    whichprocop.dir = self.cwdopt.as_ref();

	    let mut whichproc = Process::new(program, argv, whichprocop);
	    let mut process = whichproc.unwrap();
	    let mut procout = process.finish_with_output();
	    println(std::str::from_utf8(procout.output));
            */
        } else {
            println!("{:s}: command not found", program);
        }
    }

    fn cmd_exists(&mut self, cmd_path: &str) -> bool {
        let ret = run::process_output("which", [cmd_path.to_owned()]);
        return ret.expect("exit code error.").status.success();
        /*
        println("cmd_exists hit");
        let mut whichprocop = ProcessOptions::new();
        whichprocop.dir = self.cwdopt.as_ref();

        let mut whichproc = Process::new("which", [cmd_path.to_owned()], whichprocop);
        let mut process = whichproc.unwrap();
	let mut procout = process.finish();
        procout.success()
        */
    }

    //Justin's function for cd
    fn changeDir(&mut self, cmd_line: &str) {
	let mut argv: ~[~str] =
            cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();

        if argv.len() > 1 {
            let pstring: ~str = argv.remove(1);

            //println!("You want to change cwd to {:s}", pstring);

            let npath = Path::new(pstring);

            let mut cpath = getcwd();
            cpath.push(npath);

            if cpath.exists() {
		let mut cpathforopt = cpath.clone();
		std::os::change_dir(&cpath);
		// self.cwd = cpath;
            } else {
		println("Path does not exist!");
            }

        }

        let x = getcwd();

        match x.as_str() {
	    Some(path_str) => {println!("{:s}", path_str); }
	    None	=> {println("Path not representable as string!"); }
        }
    }

    fn history(&mut self, cmd_line: &str) {
      //let mut argv: ~[~str] =
    }
}

fn get_cmdline_from_args() -> Option<~str> {
    /* Begin processing program arguments and initiate the parameters. */
    let args = os::args();

    let opts = ~[
        getopts::optopt("c")
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { fail!(f.to_err_msg()) }
    };

    if matches.opt_present("c") {
        let cmd_str = match matches.opt_str("c") {
                                                Some(cmd_str) => {cmd_str.to_owned()},
                                                None => {~""}
                                              };
        return Some(cmd_str);
    } else {
        return None;
    }
}

fn main() {
    let opt_cmd_line = get_cmdline_from_args();

    match opt_cmd_line {
        Some(cmd_line) => Shell::new("").run_cmdline(cmd_line),
        None           => Shell::new("gash > ").run()
    }
}
<commit_msg>Empty vector init<commit_after>//
// gash.rs
//
// Starting code for PS2
// Running on Rust 0.9
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu, David Evans
// Version 0.4
//
/*
Vikram Bhasin vb8nd and Justin Ingram jci5kb
*/

extern mod extra;

use std::{io, run, os};
use std::io::buffered::BufferedReader;
use std::io::stdin;
use std::os::getcwd;
use extra::getopts;
use std::run::Process;
use std::run::ProcessOutput;
use std::run::ProcessOptions;
use std::option::{Option, None, Some};

struct Shell {
    cmd_prompt: ~str,
    hist: ~[~str],
}

impl Shell {
    fn new(prompt_str: &str) -> Shell {
        Shell {
            cmd_prompt: prompt_str.to_owned(),
            hist: ~[],
        }
    }

    fn run(&mut self) {
        let mut stdin = BufferedReader::new(stdin());

        loop {
            print(self.cmd_prompt);
            io::stdio::flush();

            let line = stdin.read_line().unwrap();
            let cmd_line = line.trim().to_owned();
            let program = cmd_line.splitn(' ', 1).nth(0).expect("no program");

            match program {
                ""      =>  { continue; }
                "exit"  =>  { return; }
                "cd"	=>  { self.changeDir(cmd_line); }
                "history" =>{ self.history(cmd_line); }
                _       =>  { self.run_cmdline(cmd_line); }
            }
        }
    }

    fn run_cmdline(&mut self, cmd_line: &str) {
        let mut argv: ~[~str] =
            cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();

        if argv.len() > 0 {
            let program: ~str = argv.remove(0);

            //Let's process the argv

            let endopt = argv.pop_opt();
            let end = match endopt {
		Some(stringy) => { stringy }
		None => { ~"" }
            };

            if end.eq(&~"&") {
		println("Start in a new process" + end);
            } else {
		println("No new process");
		if !end.eq(&~"") {
		    argv.push(end.to_owned());
		}
            }

            self.run_cmd(program, argv);
        }
    }

    fn run_cmd(&mut self, program: &str, argv: &[~str]) {
        if self.cmd_exists(program) {
	    // Old stuff
            run::process_status(program, argv);

            //println("Run command hit");
            //println(program);
            /*
            let mut whichprocop = ProcessOptions::new();
	    whichprocop.dir = self.cwdopt.as_ref();

	    let mut whichproc = Process::new(program, argv, whichprocop);
	    let mut process = whichproc.unwrap();
	    let mut procout = process.finish_with_output();
	    println(std::str::from_utf8(procout.output));
            */
        } else {
            println!("{:s}: command not found", program);
        }
    }

    fn cmd_exists(&mut self, cmd_path: &str) -> bool {
        let ret = run::process_output("which", [cmd_path.to_owned()]);
        return ret.expect("exit code error.").status.success();
        /*
        println("cmd_exists hit");
        let mut whichprocop = ProcessOptions::new();
        whichprocop.dir = self.cwdopt.as_ref();

        let mut whichproc = Process::new("which", [cmd_path.to_owned()], whichprocop);
        let mut process = whichproc.unwrap();
	let mut procout = process.finish();
        procout.success()
        */
    }

    //Justin's function for cd
    fn changeDir(&mut self, cmd_line: &str) {
	let mut argv: ~[~str] =
            cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();

        if argv.len() > 1 {
            let pstring: ~str = argv.remove(1);

            //println!("You want to change cwd to {:s}", pstring);

            let npath = Path::new(pstring);

            let mut cpath = getcwd();
            cpath.push(npath);

            if cpath.exists() {
		let mut cpathforopt = cpath.clone();
		std::os::change_dir(&cpath);
		// self.cwd = cpath;
            } else {
		println("Path does not exist!");
            }

        }

        let x = getcwd();

        match x.as_str() {
	    Some(path_str) => {println!("{:s}", path_str); }
	    None	=> {println("Path not representable as string!"); }
        }
    }

    fn history(&mut self, cmd_line: &str) {
      //let mut argv: ~[~str] =
    }
}

fn get_cmdline_from_args() -> Option<~str> {
    /* Begin processing program arguments and initiate the parameters. */
    let args = os::args();

    let opts = ~[
        getopts::optopt("c")
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { fail!(f.to_err_msg()) }
    };

    if matches.opt_present("c") {
        let cmd_str = match matches.opt_str("c") {
                                                Some(cmd_str) => {cmd_str.to_owned()},
                                                None => {~""}
                                              };
        return Some(cmd_str);
    } else {
        return None;
    }
}

fn main() {
    let opt_cmd_line = get_cmdline_from_args();

    match opt_cmd_line {
        Some(cmd_line) => Shell::new("").run_cmdline(cmd_line),
        None           => Shell::new("gash > ").run()
    }
}
<|endoftext|>


<commit_before>// See LICENSE file for copyright and license details.

use std::f32::consts::{
    PI,
    FRAC_PI_2,
};
use std::num::{
    sqrt,
    pow,
    sin,
    cos,
};
use cgmath::vector::{
    Vec2,
    Vec3,
    Vector,
};
use core_types::{
    Int,
    MapPos,
};
use gl_types::{
    WorldPos,
    Float,
    VertexCoord,
};

pub struct Geom {
    hex_ex_radius: Float,
    hex_in_radius: Float,
}

impl Geom {
    pub fn new() -> Geom {
        let hex_ex_radius: Float = 1.0 / 2.0;
        let hex_in_radius = sqrt(
                pow(hex_ex_radius, 2) - pow(hex_ex_radius / 2.0, 2));
        Geom {
            hex_ex_radius: hex_ex_radius,
            hex_in_radius: hex_in_radius,
        }
    }

    pub fn map_pos_to_world_pos(&self, i: MapPos) -> WorldPos {
        let v = Vec2 {
            x: (i.x as Float) * self.hex_in_radius * 2.0,
            y: (i.y as Float) * self.hex_ex_radius * 1.5,
        };
        if i.y % 2 == 0 {
            Vec3{x: v.x + self.hex_in_radius, y: v.y, z: 0.0}
        } else {
            v.extend(0.0)
        }
    }

    pub fn index_to_circle_vertex(&self, count: Int, i: Int) -> VertexCoord {
        let n = FRAC_PI_2 + 2.0 * PI * (i as Float) / (count as Float);
        Vec3{x: cos(n), y: sin(n), z: 0.0}.mul_s(self.hex_ex_radius)
    }

    pub fn index_to_hex_vertex(&self, i: Int) -> VertexCoord {
        self.index_to_circle_vertex(6, i)
    }
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<commit_msg>Geom: hex_ex_radius: 0.5 -> 1.0<commit_after>// See LICENSE file for copyright and license details.

use std::f32::consts::{
    PI,
    FRAC_PI_2,
};
use std::num::{
    sqrt,
    pow,
    sin,
    cos,
};
use cgmath::vector::{
    Vec2,
    Vec3,
    Vector,
};
use core_types::{
    Int,
    MapPos,
};
use gl_types::{
    WorldPos,
    Float,
    VertexCoord,
};

pub struct Geom {
    hex_ex_radius: Float,
    hex_in_radius: Float,
}

impl Geom {
    pub fn new() -> Geom {
        let hex_ex_radius: Float = 1.0;
        let hex_in_radius = sqrt(
                pow(hex_ex_radius, 2) - pow(hex_ex_radius / 2.0, 2));
        Geom {
            hex_ex_radius: hex_ex_radius,
            hex_in_radius: hex_in_radius,
        }
    }

    pub fn map_pos_to_world_pos(&self, i: MapPos) -> WorldPos {
        let v = Vec2 {
            x: (i.x as Float) * self.hex_in_radius * 2.0,
            y: (i.y as Float) * self.hex_ex_radius * 1.5,
        };
        if i.y % 2 == 0 {
            Vec3{x: v.x + self.hex_in_radius, y: v.y, z: 0.0}
        } else {
            v.extend(0.0)
        }
    }

    pub fn index_to_circle_vertex(&self, count: Int, i: Int) -> VertexCoord {
        let n = FRAC_PI_2 + 2.0 * PI * (i as Float) / (count as Float);
        Vec3{x: cos(n), y: sin(n), z: 0.0}.mul_s(self.hex_ex_radius)
    }

    pub fn index_to_hex_vertex(&self, i: Int) -> VertexCoord {
        self.index_to_circle_vertex(6, i)
    }
}

// vim: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
<|endoftext|>


<commit_before>// Build the library.

extern crate gcc;

use std::fs;
use std::io;
use std::path::Path;

fn main() {
    let mut conf = gcc::Config::new();

    conf.file("../boot/bootutil/src/loader.c");
    conf.file("../boot/bootutil/src/caps.c");
    conf.file("../boot/bootutil/src/bootutil_misc.c");
    conf.file("csupport/run.c");
    conf.include("../boot/bootutil/include");
    conf.include("../boot/zephyr/include");
    conf.debug(true);
    conf.flag("-Wall");
    conf.define("__BOOTSIM__", None);
    // conf.define("MCUBOOT_OVERWRITE_ONLY", None);
    conf.compile("libbootutil.a");
    walk_dir("../boot").unwrap();
    walk_dir("csupport").unwrap();
}

// Output the names of all files within a directory so that Cargo knows when to rebuild.
fn walk_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
    for ent in fs::read_dir(path.as_ref())? {
        let ent = ent?;
        let p = ent.path();
        if p.is_dir() {
            walk_dir(p)?;
        } else {
            // Note that non-utf8 names will fail.
            let name = p.to_str().unwrap();
            if name.ends_with(".c") || name.ends_with(".h") {
                println!("cargo:rerun-if-changed={}", name);
            }
        }
    }

    Ok(())
}
<commit_msg>sim: use flash_area_get_sectors()<commit_after>// Build the library.

extern crate gcc;

use std::fs;
use std::io;
use std::path::Path;

fn main() {
    let mut conf = gcc::Config::new();

    conf.file("../boot/bootutil/src/loader.c");
    conf.file("../boot/bootutil/src/caps.c");
    conf.file("../boot/bootutil/src/bootutil_misc.c");
    conf.file("csupport/run.c");
    conf.include("../boot/bootutil/include");
    conf.include("../boot/zephyr/include");
    conf.debug(true);
    conf.flag("-Wall");
    conf.define("__BOOTSIM__", None);
    // conf.define("MCUBOOT_OVERWRITE_ONLY", None);
    conf.define("MCUBOOT_USE_FLASH_AREA_GET_SECTORS", None);
    conf.compile("libbootutil.a");
    walk_dir("../boot").unwrap();
    walk_dir("csupport").unwrap();
}

// Output the names of all files within a directory so that Cargo knows when to rebuild.
fn walk_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
    for ent in fs::read_dir(path.as_ref())? {
        let ent = ent?;
        let p = ent.path();
        if p.is_dir() {
            walk_dir(p)?;
        } else {
            // Note that non-utf8 names will fail.
            let name = p.to_str().unwrap();
            if name.ends_with(".c") || name.ends_with(".h") {
                println!("cargo:rerun-if-changed={}", name);
            }
        }
    }

    Ok(())
}
<|endoftext|>