1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use std::{
    error::Error,
    net::{Ipv4Addr, SocketAddrV4, TcpListener},
};

use rand::random;

pub fn get_free_port(ip: Ipv4Addr, try_times: usize) -> Result<u16, Box<dyn Error + Send + Sync>> {
    let port = random::<u16>();
    for _ in 0..try_times {
        let addr = SocketAddrV4::new(ip, port);
        match TcpListener::bind(addr) {
            Ok(_) => {
                return Ok(port);
            }
            Err(_) => continue,
        }
    }
    Err("No free port found".into())
}

pub mod priority_lsit {
    use std::{
        collections::{linked_list, LinkedList},
        fmt::Debug,
    };

    use super::super::GetCmpType;

    fn list_insert_asc<C>(list: &mut LinkedList<C::Type>, value: C::Type)
    where
        C: Ord + GetCmpType,
        C::Type: Debug,
    {
        let mut cursor = list.cursor_front_mut();
        loop {
            match cursor.current() {
                Some(v) => {
                    if C::new(v) > C::new(&value) {
                        cursor.insert_before(value);
                        return;
                    }
                    cursor.move_next();
                }
                None => {
                    cursor.insert_before(value);
                    return;
                }
            }
        }
    }

    pub fn list_check_and_del<C>(list: &mut LinkedList<C::Type>, value: &C::Type) -> bool
    where
        C: PartialEq + GetCmpType,
        C::Type: Debug,
    {
        let mut cursor = list.cursor_front_mut();
        loop {
            match cursor.current() {
                Some(v) => {
                    if C::new(v) == C::new(&value) {
                        cursor.remove_current();
                        return true;
                    }
                    cursor.move_next();
                }
                None => return false,
            }
        }
    }

    fn list_check<C>(list: &mut LinkedList<C::Type>, value: &C::Type) -> bool
    where
        C: PartialEq + GetCmpType,
        C::Type: Debug,
    {
        let mut cursor = list.cursor_front_mut();
        loop {
            match cursor.current() {
                Some(v) => {
                    if C::new(v) == C::new(value) {
                        return true;
                    }
                    cursor.move_next();
                }
                None => return false,
            }
        }
    }

    pub fn list_insert_or_replace_asc<C>(list: &mut LinkedList<C::Type>, value: C::Type)
    where
        C: Ord + Eq + GetCmpType,
        C::Type: Debug,
    {
        list_check_and_del::<C>(list, &value);
        list_insert_asc::<C>(list, value);
    }

    pub fn get_cursor<'a, C>(
        list: &'a mut LinkedList<C::Type>,
        value: &C::Type,
    ) -> Option<linked_list::CursorMut<'a, C::Type>>
    where
        C: PartialEq + GetCmpType,
        C::Type: Debug,
    {
        let mut cursor = list.cursor_front_mut();
        loop {
            match cursor.current() {
                Some(v) => {
                    if C::new(v) == C::new(value) {
                        cursor.move_prev();
                        return Some(cursor);
                    }
                    cursor.move_next();
                }
                None => return None,
            }
        }
    }
}