Implement basic networking code
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Build library & run tests / build (push) Successful in 42s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Build library & run tests / build (push) Successful in 42s
				
			This commit is contained in:
		
							parent
							
								
									971e185ae5
								
							
						
					
					
						commit
						06aa6a1f71
					
				
							
								
								
									
										199
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										199
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @ -32,6 +32,27 @@ dependencies = [ | ||||
|  "rustc-demangle", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "base64" | ||||
| version = "0.21.7" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "bitflags" | ||||
| version = "2.5.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" | ||||
| dependencies = [ | ||||
|  "serde", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "bytes" | ||||
| version = "1.6.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "cc" | ||||
| version = "1.0.99" | ||||
| @ -51,6 +72,7 @@ dependencies = [ | ||||
|  "proc-macro2", | ||||
|  "quote", | ||||
|  "rand", | ||||
|  "ron", | ||||
|  "serde", | ||||
|  "syn", | ||||
|  "tokio", | ||||
| @ -100,6 +122,17 @@ dependencies = [ | ||||
|  "adler", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "mio" | ||||
| version = "0.8.11" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" | ||||
| dependencies = [ | ||||
|  "libc", | ||||
|  "wasi", | ||||
|  "windows-sys 0.48.0", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "num_cpus" | ||||
| version = "1.16.0" | ||||
| @ -179,6 +212,18 @@ dependencies = [ | ||||
|  "getrandom", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "ron" | ||||
| version = "0.8.1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" | ||||
| dependencies = [ | ||||
|  "base64", | ||||
|  "bitflags", | ||||
|  "serde", | ||||
|  "serde_derive", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "rustc-demangle" | ||||
| version = "0.1.24" | ||||
| @ -205,6 +250,16 @@ dependencies = [ | ||||
|  "syn", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "socket2" | ||||
| version = "0.5.7" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" | ||||
| dependencies = [ | ||||
|  "libc", | ||||
|  "windows-sys 0.52.0", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "syn" | ||||
| version = "2.0.66" | ||||
| @ -223,9 +278,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" | ||||
| dependencies = [ | ||||
|  "backtrace", | ||||
|  "bytes", | ||||
|  "libc", | ||||
|  "mio", | ||||
|  "num_cpus", | ||||
|  "pin-project-lite", | ||||
|  "socket2", | ||||
|  "tokio-macros", | ||||
|  "windows-sys 0.48.0", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| @ -250,3 +310,142 @@ name = "wasi" | ||||
| version = "0.11.0+wasi-snapshot-preview1" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows-sys" | ||||
| version = "0.48.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" | ||||
| dependencies = [ | ||||
|  "windows-targets 0.48.5", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows-sys" | ||||
| version = "0.52.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" | ||||
| dependencies = [ | ||||
|  "windows-targets 0.52.5", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows-targets" | ||||
| version = "0.48.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" | ||||
| dependencies = [ | ||||
|  "windows_aarch64_gnullvm 0.48.5", | ||||
|  "windows_aarch64_msvc 0.48.5", | ||||
|  "windows_i686_gnu 0.48.5", | ||||
|  "windows_i686_msvc 0.48.5", | ||||
|  "windows_x86_64_gnu 0.48.5", | ||||
|  "windows_x86_64_gnullvm 0.48.5", | ||||
|  "windows_x86_64_msvc 0.48.5", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows-targets" | ||||
| version = "0.52.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" | ||||
| dependencies = [ | ||||
|  "windows_aarch64_gnullvm 0.52.5", | ||||
|  "windows_aarch64_msvc 0.52.5", | ||||
|  "windows_i686_gnu 0.52.5", | ||||
|  "windows_i686_gnullvm", | ||||
|  "windows_i686_msvc 0.52.5", | ||||
|  "windows_x86_64_gnu 0.52.5", | ||||
|  "windows_x86_64_gnullvm 0.52.5", | ||||
|  "windows_x86_64_msvc 0.52.5", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_aarch64_gnullvm" | ||||
| version = "0.48.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_aarch64_gnullvm" | ||||
| version = "0.52.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_aarch64_msvc" | ||||
| version = "0.48.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_aarch64_msvc" | ||||
| version = "0.52.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_i686_gnu" | ||||
| version = "0.48.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_i686_gnu" | ||||
| version = "0.52.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_i686_gnullvm" | ||||
| version = "0.52.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_i686_msvc" | ||||
| version = "0.48.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_i686_msvc" | ||||
| version = "0.52.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_x86_64_gnu" | ||||
| version = "0.48.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_x86_64_gnu" | ||||
| version = "0.52.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_x86_64_gnullvm" | ||||
| version = "0.48.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_x86_64_gnullvm" | ||||
| version = "0.52.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_x86_64_msvc" | ||||
| version = "0.48.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "windows_x86_64_msvc" | ||||
| version = "0.52.5" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" | ||||
|  | ||||
| @ -9,10 +9,11 @@ publish = ["gitea"] | ||||
| proc-macro2 = "1.0.85" | ||||
| quote = "1.0.36" | ||||
| rand = "0.8.5" | ||||
| ron = "0.8.1" | ||||
| serde = { version = "1.0.203", features = ["serde_derive"] } | ||||
| syn = "2.0.66" | ||||
| # TODO: rt and macros should be removed unless we do tests | ||||
| tokio = { version = "1.38.0", features = ["sync", "rt-multi-thread", "macros", "time"] } | ||||
| tokio = { version = "1.38.0", features = ["sync", "rt-multi-thread", "macros", "time", "io-util", "net"] } | ||||
| 
 | ||||
| [lib] | ||||
| proc-macro = true | ||||
|  | ||||
| @ -19,7 +19,7 @@ | ||||
|           doCheck = true; | ||||
|         }; | ||||
|         devShell = with pkgs; mkShell { | ||||
|           nativeBuildInputs = with pkgs; [rustc cargo rustfmt pre-commit clippy]; | ||||
|           nativeBuildInputs = with pkgs; [rustc cargo rustfmt pre-commit clippy cargo-expand]; | ||||
|         }; | ||||
|       }); | ||||
| } | ||||
							
								
								
									
										59
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								src/lib.rs
									
									
									
									
									
								
							| @ -42,7 +42,8 @@ fn derive_protocol(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream | ||||
|     let question_enum_name = format_ident!("__{}Question", name); | ||||
|     let query_enum_name = format_ident!("__{}Query", name); | ||||
|     let queries_struct_name = format_ident!("__{}Queries", name); | ||||
|     let server_trait_name = format_ident!("{}Server", name); | ||||
|     let client_connection_struct_name = format_ident!("__{}Connection", name); | ||||
|     let server_trait_name = format_ident!("{}ServerTrait", name); | ||||
|     let client_struct_name = format_ident!("{}Client", name); | ||||
| 
 | ||||
|     let vis = &input.vis; | ||||
| @ -210,6 +211,59 @@ fn derive_protocol(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|     // Create a struct to handle the connection from the client to the server
 | ||||
|     let stream_type = quote! { tokio::net::TcpStream }; // TODO: In the future we could support other stream types
 | ||||
|     let cc_struct = quote! { | ||||
|         struct #client_connection_struct_name { | ||||
|             to_send: tokio::sync::mpsc::Receiver<(u64, #question_enum_name)>, | ||||
|             received: tokio::sync::mpsc::Sender<(u64, #answer_enum_name)>, | ||||
|             stream: #stream_type, | ||||
|         } | ||||
|         impl #client_connection_struct_name { | ||||
|             pub fn new( | ||||
|                 to_send: tokio::sync::mpsc::Receiver<(u64, #question_enum_name)>, | ||||
|                 received: tokio::sync::mpsc::Sender<(u64, #answer_enum_name)>, | ||||
|                 stream: #stream_type, | ||||
|             ) -> Self { | ||||
|                 Self { | ||||
|                     to_send, | ||||
|                     received, | ||||
|                     stream, | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             pub async fn run(mut self) { | ||||
|                 use tokio::io::AsyncWriteExt; | ||||
|                 use tokio::io::AsyncReadExt; | ||||
|                 let mut buf = Vec::with_capacity(1024); | ||||
|                 loop { | ||||
|                     tokio::select! { | ||||
|                         Some((nonce, query)) = self.to_send.recv() => { | ||||
|                             let serialized = ron::ser::to_string(&query).expect("Failed to serialize query!"); | ||||
|                             let len = serialized.len() as u32; | ||||
|                             self.stream.write_all(&len.to_le_bytes()).await.expect("Failed to write length!"); | ||||
|                             self.stream.write_all(serialized.as_bytes()).await.expect("Failed to write query!"); | ||||
|                         }, | ||||
|                         Ok(_) = self.stream.readable() => { | ||||
|                             match self.stream.try_read(&mut buf) { | ||||
|                                 Ok(0) => break, // Stream closed
 | ||||
|                                 Ok(n) => { | ||||
|                                     // TODO: This doesn't cope with partial reads, we will handle that later
 | ||||
|                                     let len = u32::from_le_bytes(buf[..4].try_into().expect("Failed to convert bytes to u32")); | ||||
|                                     let serialized = std::str::from_utf8(&buf[4..(4 + len as usize)]).expect("Failed to convert bytes to string"); | ||||
|                                     let query: #answer_enum_name = ron::de::from_str(serialized).expect("Failed to deserialize query!"); | ||||
|                                     self.received.send((0, query)).await.expect("Failed to send query!"); | ||||
|                                     buf.clear(); | ||||
|                                 }, | ||||
|                                 Err(ref e) if e.kind() == ::std::io::ErrorKind::WouldBlock => { continue; }, | ||||
|                                 Err(e) => eprintln!("Error reading from stream: {:?}", e), | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|     // Create a struct which the client will use to communicate
 | ||||
|     let client_recv_queue_wrapper = format_ident!("__{}RecvQueueWrapper", name); | ||||
|     let client_struct = quote! { | ||||
| @ -232,7 +286,7 @@ fn derive_protocol(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream | ||||
|             queries: #queries_struct_name, | ||||
|             send_queue: tokio::sync::mpsc::Sender<(u64, #question_enum_name)>, | ||||
|             recv_queue: #client_recv_queue_wrapper, | ||||
|         } // TODO: This struct will have some fields to handle the actual connection
 | ||||
|         } | ||||
|         impl #client_struct_name { | ||||
|             pub fn new(send_queue: tokio::sync::mpsc::Sender<(u64, #question_enum_name)>, recv_queue: tokio::sync::mpsc::Receiver<(u64, #answer_enum_name)>) -> Self { | ||||
|                 Self { | ||||
| @ -279,6 +333,7 @@ fn derive_protocol(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream | ||||
|         #query_enum | ||||
|         #queries_struct | ||||
|         #server_trait | ||||
|         #cc_struct | ||||
|         #client_struct | ||||
|     }; | ||||
|     expanded | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user