LINUX.ORG.RU

История изменений

Исправление zurg, (текущая версия) :

Да, отработает с логическим багом, но это именно прямое переписывание в лоб плюсового варианта. Такая версия:

struct Conn<State> {
    st: State
}
struct Disconnected;
struct Connecting;
struct Connected;

impl<State> Conn<State> {
    pub fn new()-> Conn<Disconnected> {
        Conn{ st: Disconnected }
    }
}
impl Conn<Disconnected> {
    pub fn connect(self) -> Conn<Connecting> {
        est();
        Conn{ st: Connecting }
    }
}
impl Conn<Connecting> {
    pub fn estable(self) -> Conn<Connected> {
        Conn{ st: Connected }
    }
}
impl Conn<Connected> {
    pub fn ping(self, valid: bool) -> Conn<Connected> {
        if valid { reset() };
        Conn{ st: Connected }
    }
    pub fn timeout(self) -> Conn<Connecting> {
        est();
        Conn{ st: Connecting }
    }
    pub fn disconnect(self) -> Conn<Disconnected> {
        close();
        Conn{ st: Disconnected }
    }
}
pub fn main() { 
    let conn = Conn::<Disconnected>::new();
    //let conn = conn.ping(true);  // ошибка компиляции
    let conn = conn.connect();
    let conn = conn.estable();
    let conn = conn.ping(true);
    let conn = conn.disconnect();
 
    assert!( size_of::<Conn<Connected> >() == 0);
}

https://godbolt.org/z/1qqo64MsT и вот это в плюсах повторить нельзя, по крайней мере практически. Оно статически проверяет правильность последовательности переходов состояний, плюс чистый зерокост и по тактам и по памяти, в плюсах тоже зерокост можно, но последовательность придётся проверять в рантайме, в сишке вообще всё в рантайм уедет (ну или на CVE.org) И это всё ещё изкоробочный раст, без библиотек

Исходная версия zurg, :

Да, отработает с логическим багом, но это именно прямое переписывание в лоб плюсового варианта. Такая версия:

struct Conn<State> {
    st: State
}
struct Disconnected;
struct Connecting;
struct Connected;

impl<State> Conn<State> {
    pub fn new()-> Conn<Disconnected> {
        Conn{ st: Disconnected }
    }
}
impl Conn<Disconnected> {
    pub fn connect(self) -> Conn<Connecting> {
        est();
        Conn{ st: Connecting }
    }
}
impl Conn<Connecting> {
    pub fn estable(self) -> Conn<Connected> {
        Conn{ st: Connected }
    }
}
impl Conn<Connected> {
    pub fn ping(self, valid: bool) -> Conn<Connected> {
        if valid { reset() };
        Conn{ st: Connected }
    }
    pub fn timeout(self) -> Conn<Connecting> {
        est();
        Conn{ st: Connecting }
    }
    pub fn disconnect(self) -> Conn<Disconnected> {
        close();
        Conn{ st: Disconnected }
    }
}
pub fn main() { 
    let conn = Conn::<Disconnected>::new();
    //let conn = conn.ping(true);  // ошибка компиляции
    let conn = conn.connect();
    let conn = conn.estable();
    let conn = conn.ping(true);
    let conn = conn.disconnect();
 
    assert!( size_of::<Conn<Connected> >() == 0);
}

https://godbolt.org/z/1qqo64MsT и вот это в плюсах повторить нельзя, по крайней мере практически. Оно статически проверяет правильность последовательности переходов состояний, плюс чистый зерокост и по тактам и по памяти, в плюсах тоже зерокост можно, но последовательность придётся проверять в рантайме, в сишке вообще всё в рантайм уедет (ну или на CVE.org)