intuicio_frontend_simpleton/library/
net.rs

1use super::bytes::Bytes;
2use crate::{Boolean, Integer, Reference, Text};
3use intuicio_core::{registry::Registry, IntuicioStruct};
4use intuicio_derive::{intuicio_method, intuicio_methods, IntuicioStruct};
5use std::{
6    io::{Read, Write},
7    net::{TcpListener, TcpStream},
8};
9
10#[derive(IntuicioStruct, Default)]
11#[intuicio(name = "Server", module_name = "net_server")]
12pub struct Server {
13    #[intuicio(ignore)]
14    listener: Option<TcpListener>,
15}
16
17#[intuicio_methods(module_name = "net_server")]
18impl Server {
19    #[allow(clippy::new_ret_no_self)]
20    #[intuicio_method(use_registry)]
21    pub fn new(registry: &Registry, address: Reference) -> Reference {
22        let address = address.read::<Text>().unwrap();
23        Reference::new(
24            Server {
25                listener: Some(TcpListener::bind(address.as_str()).unwrap()),
26            },
27            registry,
28        )
29    }
30
31    #[intuicio_method(use_registry)]
32    pub fn set_nonblocking(registry: &Registry, server: Reference, mode: Reference) -> Reference {
33        let server = server.read::<Server>().unwrap();
34        let mode = *mode.read::<Boolean>().unwrap();
35        Reference::new_boolean(
36            server
37                .listener
38                .as_ref()
39                .unwrap()
40                .set_nonblocking(mode)
41                .is_ok(),
42            registry,
43        )
44    }
45
46    #[intuicio_method(use_registry)]
47    pub fn accept(registry: &Registry, server: Reference) -> Reference {
48        let server = server.read::<Server>().unwrap();
49        if let Ok((stream, _)) = server.listener.as_ref().unwrap().accept() {
50            Reference::new(
51                Channel {
52                    stream: Some(stream),
53                },
54                registry,
55            )
56        } else {
57            Reference::null()
58        }
59    }
60}
61
62#[derive(IntuicioStruct, Default)]
63#[intuicio(name = "Channel", module_name = "net_channel")]
64pub struct Channel {
65    #[intuicio(ignore)]
66    stream: Option<TcpStream>,
67}
68
69#[intuicio_methods(module_name = "net_channel")]
70impl Channel {
71    #[intuicio_method(use_registry)]
72    pub fn connect(registry: &Registry, address: Reference) -> Reference {
73        let address = address.read::<Text>().unwrap();
74        let stream = TcpStream::connect(address.as_str()).unwrap();
75        Reference::new(
76            Channel {
77                stream: Some(stream),
78            },
79            registry,
80        )
81    }
82
83    #[intuicio_method(use_registry)]
84    pub fn set_nonblocking(registry: &Registry, channel: Reference, mode: Reference) -> Reference {
85        let channel = channel.read::<Channel>().unwrap();
86        let mode = *mode.read::<Boolean>().unwrap();
87        Reference::new_boolean(
88            channel
89                .stream
90                .as_ref()
91                .unwrap()
92                .set_nonblocking(mode)
93                .is_ok(),
94            registry,
95        )
96    }
97
98    #[intuicio_method(use_registry)]
99    pub fn set_no_delay(registry: &Registry, channel: Reference, mode: Reference) -> Reference {
100        let channel = channel.read::<Channel>().unwrap();
101        let mode = *mode.read::<Boolean>().unwrap();
102        Reference::new_boolean(
103            channel.stream.as_ref().unwrap().set_nodelay(mode).is_ok(),
104            registry,
105        )
106    }
107
108    #[intuicio_method(use_registry)]
109    pub fn read(registry: &Registry, mut channel: Reference, size: Reference) -> Reference {
110        let mut channel = channel.write::<Channel>().unwrap();
111        let size = *size.read::<Integer>().unwrap() as usize;
112        let mut result = vec![0; size];
113        if channel.stream.as_mut().unwrap().read(&mut result).is_ok() {
114            Reference::new(Bytes::new_raw(result), registry)
115        } else {
116            Reference::null()
117        }
118    }
119
120    #[intuicio_method(use_registry)]
121    pub fn write(registry: &Registry, mut channel: Reference, buffer: Reference) -> Reference {
122        let mut channel = channel.write::<Channel>().unwrap();
123        let buffer = buffer.read::<Bytes>().unwrap();
124        Reference::new_boolean(
125            channel
126                .stream
127                .as_mut()
128                .unwrap()
129                .write(buffer.get_ref())
130                .is_ok(),
131            registry,
132        )
133    }
134}
135
136pub fn install(registry: &mut Registry) {
137    registry.add_type(Server::define_struct(registry));
138    registry.add_function(Server::new__define_function(registry));
139    registry.add_function(Server::set_nonblocking__define_function(registry));
140    registry.add_function(Server::accept__define_function(registry));
141    registry.add_type(Channel::define_struct(registry));
142    registry.add_function(Channel::connect__define_function(registry));
143    registry.add_function(Channel::set_nonblocking__define_function(registry));
144    registry.add_function(Channel::set_no_delay__define_function(registry));
145    registry.add_function(Channel::read__define_function(registry));
146    registry.add_function(Channel::write__define_function(registry));
147}