├── .gitignore ├── .idea ├── misc.xml ├── modules.xml └── vcs.xml ├── Cargo.toml ├── LICENSE ├── README.md ├── RxRust ├── Cargo.toml └── src │ └── main.rs ├── SQUICD ├── Cargo.lock ├── Cargo.toml ├── README.md ├── cert.crt ├── cert.key └── src │ ├── bin │ └── client_main.rs │ ├── common.rs │ ├── dsl.rs │ ├── lib.rs │ └── main.rs ├── actix ├── Cargo.toml ├── actix.iml ├── src │ ├── actix_server.rs │ ├── actix_web_server.rs │ └── main.rs └── static │ └── index.html ├── actor_model ├── Cargo.toml └── src │ └── main.rs ├── ai_api_integration ├── Cargo.toml ├── README.md ├── index.html ├── pkg │ ├── README.md │ ├── ai_api_integration.d.ts │ ├── ai_api_integration.js │ ├── ai_api_integration_bg.wasm │ ├── ai_api_integration_bg.wasm.d.ts │ └── package.json └── src │ └── lib.rs ├── architecture ├── Cargo.toml └── src │ ├── circuit_breaker.rs │ └── main.rs ├── dragon_ball ├── Cargo.toml ├── README.md ├── assets │ ├── android_17.png │ ├── android_17_player.png │ ├── android_18.png │ ├── android_18_player.png │ ├── background.png │ ├── dbz.ogg │ ├── dr_hero.png │ ├── dr_hero_player.png │ ├── trunk.png │ ├── trunk_b.png │ └── trunk_player.png └── src │ └── main.rs ├── dynamic_loading ├── Cargo.toml └── src │ └── main.rs ├── dynamic_loading_contract ├── Cargo.toml └── src │ └── lib.rs ├── dynamic_loading_plugin ├── Cargo.toml └── src │ └── lib.rs ├── game_3d ├── Cargo.toml └── src │ ├── board.rs │ ├── director.rs │ ├── main.rs │ └── player.rs ├── golden_axe ├── Cargo.toml ├── README.md ├── assets │ ├── Heninger.png │ ├── Longmoan.png │ ├── Storchinaya.png │ ├── background.png │ ├── barbarian.png │ ├── logo.png │ └── player.png └── src │ └── main.rs ├── goose ├── Cargo.toml ├── goose.iml └── src │ ├── goose_load_test.rs │ ├── main.rs │ └── mock_http_server.rs ├── img ├── actix-web.png ├── bevy.png ├── design.png ├── kafka.png ├── lambda.jpg ├── reactivex.png ├── red_panda.png ├── rust.jpg └── tc.png ├── index.html ├── kafka ├── Cargo.toml ├── kafka.iml ├── resources │ └── uuid.txt └── src │ ├── kafka_consumer.rs │ ├── kafka_producer.rs │ └── main.rs ├── monkey_island ├── Cargo.toml ├── README.md ├── assets │ ├── background.png │ ├── guybrush.png │ ├── guybrush_monkey.png │ ├── lechuck.png │ ├── logo.png │ └── monkey_island.ogg ├── img │ └── game.png └── src │ └── main.rs ├── patterns ├── Cargo.toml ├── README.md └── src │ ├── behavioral │ ├── chain_of_responsibility.rs │ ├── memento.rs │ ├── mod.rs │ └── strategy.rs │ ├── creational │ ├── builder.rs │ ├── factory.rs │ ├── mod.rs │ └── singleton.rs │ ├── main.rs │ └── structural │ ├── composite.rs │ ├── decorator.rs │ ├── facade.rs │ └── mod.rs ├── physics_engine ├── Cargo.toml └── src │ ├── ball.rs │ ├── launcher.rs │ ├── main.rs │ └── walls.rs ├── quiche-feature ├── Cargo.toml ├── README.md ├── cert.crt ├── cert.key ├── img │ ├── output-2.png │ ├── output-3.png │ └── output.png └── src │ └── bin │ ├── client.rs │ └── server.rs ├── red_panda ├── Cargo.toml ├── red_panda.iml ├── resources │ └── uuid.txt └── src │ ├── red_panda_consumer.rs │ └── red_panda_producer.rs ├── red_panda_benchmark ├── Cargo.toml ├── README.md ├── resources │ └── uuid.txt └── src │ ├── consume_load_test.rs │ ├── produce_consume_load_test.rs │ ├── produce_load_test.rs │ └── red_panda_proxy_server.rs ├── rust_ai_dsl ├── Cargo.toml └── src │ └── main.rs ├── rust_ai_model ├── Cargo.toml └── src │ └── main.rs ├── rust_chain ├── Cargo.toml └── src │ └── main.rs ├── rust_io ├── Cargo.lock ├── Cargo.toml ├── README.md └── src │ └── lib.rs ├── src ├── features │ ├── async_programming.rs │ ├── channels_feature.rs │ ├── collection.rs │ ├── currying_function.rs │ ├── dependency_injection.rs │ ├── do_notation_style.rs │ ├── effect_system.rs │ ├── either_monad.rs │ ├── enum_type.rs │ ├── extension_method.rs │ ├── functions.rs │ ├── lens.rs │ ├── memory_management.rs │ ├── mod.rs │ ├── monad.rs │ ├── new_types.rs │ ├── pattern_matching.rs │ ├── promise.rs │ ├── race_futures.rs │ ├── rust_io.rs │ ├── rust_io_impl.rs │ ├── smart_pointer.rs │ ├── try_monad.rs │ ├── type_classes.rs │ └── union_type.rs └── main.rs ├── street_fighter ├── Cargo.toml ├── README.md ├── assets │ ├── background.png │ ├── fight.ogg │ ├── hadooken.ogg │ ├── ken.png │ ├── ken_player.png │ ├── ryu.png │ ├── ryu_player.png │ └── shoryuken.ogg └── src │ └── main.rs ├── street_of_rage ├── Cargo.toml ├── README.md ├── assets │ ├── axel.png │ ├── logo.png │ ├── punk.png │ ├── red.png │ ├── round.png │ ├── skin.png │ ├── street.png │ └── street_extra.png └── src │ └── main.rs ├── test_container ├── Cargo.toml └── src │ └── main.rs └── tokio ├── Cargo.toml ├── build.rs ├── proto └── grpc_service.proto ├── src ├── main.rs ├── tokio_async.rs ├── tokio_green_thread.rs ├── tokio_grpc_client.rs ├── tokio_grpc_server.rs ├── tokio_http_hyper.rs └── tokio_select.rs └── tokio.iml /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | debug/78p9o´pç 4 | ç`´pñ´ñ.l.nc xz<>zxcvgbhjklñ´ññ¨´-.–.*.pdb 5 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "FunctionalRust" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | futures = "0.3" 10 | rand = "0.8.5" 11 | do-notation="0.1.3" 12 | async-std = "1.12.0" 13 | pl-lens = "1.0" 14 | rust_io="0.6.0" 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Pablo Picouto Garcia 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /RxRust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "RxRust" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | rxrust="1.0.0-beta.8" -------------------------------------------------------------------------------- /SQUICD/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "SQUICD" 3 | version = "0.1.1" 4 | authors = ["politrons"] 5 | edition = "2021" 6 | license = "MIT OR Apache-2.0" 7 | description = "Squicd is a Domain-Specific Language (DSL) in Rust designed to simplify the creation of QUIC-based servers and clients for message passing." 8 | repository = "https://github.com/politrons/FunctionalRust/tree/main/SQUICD" 9 | homepage = "https://github.com/politrons/FunctionalRust/tree/main/SQUICD" 10 | readme = "README.md" 11 | 12 | [dependencies] 13 | quiche ="0.22.0" 14 | serde = { version = "1.0", features = ["derive"] } 15 | serde_cbor = "0.11" # For CBOR serialization 16 | flate2 = "1.0" # For compression 17 | ring = "0.17.8" 18 | url = "2.5.2" 19 | mio = { version = "0.8", features = ["net", "os-poll"] } 20 | log = "0.4.22" 21 | rand = "0.9.0-alpha.2" 22 | env_logger = "0.11.5" 23 | -------------------------------------------------------------------------------- /SQUICD/README.md: -------------------------------------------------------------------------------- 1 | # Squicd 2 | 3 | Author: Pablo Picouto Garcia 4 | 5 | Is this project useful? Please ⭐ Star this repository and share the love. 6 | 7 | Squicd is a Domain-Specific Language (DSL) in Rust designed to simplify the creation of QUIC-based servers and clients for message passing. 8 | 9 | ## Usage 10 | 11 | ### Setting Up the Server 12 | 13 | ```rust 14 | use squicd::dsl::Squicd; 15 | use squicd::common::Message; 16 | 17 | fn main() { 18 | Squicd::with_handler(|message: Message| { 19 | println!("Received message: {:?}", message); 20 | // Additional processing... 21 | }) 22 | .with_error_handler( 23 | |err| { 24 | // Handle side effects 25 | }) 26 | .with_cert("cert.crt") 27 | .with_key("cert.key") 28 | .with_port("4433") 29 | .start(); 30 | } 31 | 32 | ``` 33 | 34 | ### Sending Messages 35 | ```rust 36 | use squicd::common::Message; 37 | use squicd::dsl::Squicd; 38 | 39 | fn main() { 40 | let message = Message { 41 | id: 1, 42 | content: "Hello, Squicd!".to_string(), 43 | timestamp: 1234567890, 44 | }; 45 | 46 | if let Err(e) = Squicd::send_message("127.0.0.1:4433", message) { 47 | eprintln!("Error sending message: {:?}", e); 48 | } 49 | } 50 | 51 | ``` 52 | 53 | ## How It Works 54 | 55 | * Initialization: Configure the server with the provided certificate, key, and port. 56 | 57 | * Starting the Server: Call start() to begin listening for incoming QUIC connections. 58 | * Accepting Connections: New QUIC connections are accepted using the quiche library. 59 | * Receiving Messages: Messages are decompressed, deserialized, and passed to the message handler. 60 | * Processing Messages: The message handler processes incoming messages and can send responses or forward messages. 61 | * Sending Messages: Use send_message to establish a QUIC connection and send messages to other services. -------------------------------------------------------------------------------- /SQUICD/cert.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIID9zCCAt+gAwIBAgIULoZhwUi3b2HAQZtwpWkiHpcSqDcwDQYJKoZIhvcNAQEL 3 | BQAwgYoxCzAJBgNVBAYTAkVTMQ8wDQYDVQQIDAZNYWRyaWQxDzANBgNVBAcMBk1h 4 | ZHJpZDESMBAGA1UECgwJcG9saXRyb25zMRIwEAYDVQQLDAlwb2xpdHJvbnMxDTAL 5 | BgNVBAMMBFBhdWwxIjAgBgkqhkiG9w0BCQEWE3BvbGl0cm9uc0BnbWFpbC5jb20w 6 | HhcNMjQxMDE1MDkyMTM4WhcNMjUxMDE1MDkyMTM4WjCBijELMAkGA1UEBhMCRVMx 7 | DzANBgNVBAgMBk1hZHJpZDEPMA0GA1UEBwwGTWFkcmlkMRIwEAYDVQQKDAlwb2xp 8 | dHJvbnMxEjAQBgNVBAsMCXBvbGl0cm9uczENMAsGA1UEAwwEUGF1bDEiMCAGCSqG 9 | SIb3DQEJARYTcG9saXRyb25zQGdtYWlsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD 10 | ggEPADCCAQoCggEBANIWTKfAbrlrhvSDLtveakPN0Yv5W5fFyS+vCtzBRGpsy3o+ 11 | l7Kd8+3MLDWAiBQlWS+v8AXspAgot7AYqPQFUDqT48Gl9wXVXXaiSoGyPjcgt24F 12 | 49iIctJW2Skz2E+3865KA9TmgLssXd0WKlDRA5RNHeTivKL2avQUPBagBpNoNxMw 13 | 12vZfLN999wgFS9qZBgFdBiroWg/JRznLQszvJdzbnzyNDlIjCYoSLE82x2EY5Lw 14 | IqVpv0uAl44/9FGljMUKHXwAn+glEJHlH887PKO3Wa3+hhmPTJIKdglIi9XmCeqY 15 | HaxTImy3DzABdPjkG9Tyn5j8lyef6pomRfqZ828CAwEAAaNTMFEwHQYDVR0OBBYE 16 | FAl4Q/pZEg8r+J9SDhM/z+mSSGvLMB8GA1UdIwQYMBaAFAl4Q/pZEg8r+J9SDhM/ 17 | z+mSSGvLMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAB+wS24+ 18 | 8vPIbOmLM/KtkEy8LdCJzvZ0Rttm+CpNRpSAS3PsxF6gcwYJiib5hQnFNR5tD6Hh 19 | hmj3S1fRCUIqLyGtWPRe5SKaWpOImL4Qqlp0Pbft7cE/oGqqSNBrmCxPHew6ADHW 20 | 1Ut/azHeKxMmN8sh+mFOzZ90JyKGF2/+uSS4iifQmnMX48b8U9h5wW/cX5jvAx5U 21 | X2plsTYZbsXdH2vfVoBH0q8WRs9daSAEHW2rHiuKZLA/3kiQUeqePB/7uGx22PFl 22 | lUO7CNQ0L1Rm+58pd8T5g/KiDL2PCwAzjk5N4sBdQTkmaNjSPO7bQ3DtXZMdIXWa 23 | 5qoblH4d+9+zl2M= 24 | -----END CERTIFICATE----- 25 | -------------------------------------------------------------------------------- /SQUICD/cert.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDSFkynwG65a4b0 3 | gy7b3mpDzdGL+VuXxckvrwrcwURqbMt6PpeynfPtzCw1gIgUJVkvr/AF7KQIKLew 4 | GKj0BVA6k+PBpfcF1V12okqBsj43ILduBePYiHLSVtkpM9hPt/OuSgPU5oC7LF3d 5 | FipQ0QOUTR3k4ryi9mr0FDwWoAaTaDcTMNdr2XyzfffcIBUvamQYBXQYq6FoPyUc 6 | 5y0LM7yXc2588jQ5SIwmKEixPNsdhGOS8CKlab9LgJeOP/RRpYzFCh18AJ/oJRCR 7 | 5R/POzyjt1mt/oYZj0ySCnYJSIvV5gnqmB2sUyJstw8wAXT45BvU8p+Y/Jcnn+qa 8 | JkX6mfNvAgMBAAECggEAFVdpkxLzzIc1TupynKhD8D5cvpTmrozLiroD5vgFHLCP 9 | nQv1uhHcoTf/97FmYXGH1VXQkrF+2ktUmaFvrFZL15+FX/sdlGyf0XjcC7/RHSWI 10 | LLeRdUIrM93ZsptPKo37xaVELWD7C8iOgnKJeus4q1yIIGO+GOniZIgXsI6yDFA3 11 | KEadypUnwd0XpkbazIKsdxY+/nUu9efPuAKBRF0h/rVYjBEzMq7FsI7xspOmgPpC 12 | eLXjpVZwvQBaXDYVwb5kW/KT1yu3YJ1v9/+jyzCeo6A7Ea5GmuuxGZdY+LZ1jReP 13 | lOupWQRTI3TDU3ys1vzl3uoVrsiJNoz324oO/gpXjQKBgQD4xr0vzByLuajtGuhI 14 | 657m+WgjmbYnkJm/7e4Yf4VhAh10VStKBj4t0wp759eTbCZ7hd9Tc+Y3ZzoRHtEl 15 | J88EcIE3vZi2MmQ8Fj4uy4jaROYTmUUVs3s2rcKi++wC4lk/+L2qZYe5eVJdcYTl 16 | x1tN0bs8VMJxj7xCYdwBmLCwIwKBgQDYL/eGvTbX07ZCjg5mhhHIEs0ljjLZkT9k 17 | 69Nd14OVmHnTHB3FCggayelSN6VW5WIoTpNS7JpZhRAK8QB9OhkNU11H4ptrL/HC 18 | EQmP1NN6wmCA0jT1OgTvLZLhy+rWwj/C1Oh+mBPKoSV8dUDFlC0UsjeTh6pBn0Po 19 | flq+MoY+RQKBgQCHwFsoI+dHz64AhHhQolJ5k4tiMdSWTm+3rewI7j0oLHFKM9eF 20 | c1amxsynxGF8jr2JFgpBjbMIdInZIcnazphGweWhNxKICYNszm5sNqCdCo/KDg8G 21 | woPv2G2nZnTpNf6hy+gjfXfMnAl3+CQfBuQp2NKlH1NjiJ2gU6osLNftpQKBgQCW 22 | fzXqp5ghQXH0/R2LQ7PnOydzCH3ftdyS7hSzlE82+fF9BGq4+5XOyFbT9Ib2ajMd 23 | 6i1nIe0FertDUqjLhIFiJHGglGErijHbrq6gYUFjiSNTKoLRYDWFJ43EAIgYPxvS 24 | DxNW5ZmJiwskjB+uK8wCR1qnKl9c1XmZxTR4iYWonQKBgHJRXT3ag5tmCusFU5eX 25 | uqNMCb4YjDQL1+5G7wEeUZzjZ+15h2zdBdbkeNlUm9DBmc/zVkuSuYd4zocIxihX 26 | aweDr2GGSJ+o9w6qT0OMAlCG8JWEG5EVL5d/NqZF8r+WNIzxyfsm3jd1QYCFRj9T 27 | PaPdNC24OkVsIy/hPgd/ra+S 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /SQUICD/src/common.rs: -------------------------------------------------------------------------------- 1 | use serde::{Serialize, Deserialize}; 2 | use serde_cbor; 3 | use flate2::write::ZlibEncoder; 4 | use flate2::read::ZlibDecoder; 5 | use flate2::Compression; 6 | use std::io::{Read, Write}; 7 | 8 | #[derive(Serialize, Deserialize, Debug)] 9 | pub struct Message { 10 | pub id: u32, 11 | pub content: String, 12 | pub timestamp: u64, 13 | } 14 | 15 | pub fn serialize_and_compress(message: &Message) -> Result, Box> { 16 | // Serialize the message to CBOR format 17 | let serialized = serde_cbor::to_vec(message)?; 18 | 19 | // Compress the serialized data 20 | let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default()); 21 | encoder.write_all(&serialized)?; 22 | let compressed = encoder.finish()?; 23 | 24 | Ok(compressed) 25 | } 26 | 27 | pub fn decompress_and_deserialize(data: &[u8]) -> Result> { 28 | // Decompress the data 29 | let mut decoder = ZlibDecoder::new(data); 30 | let mut decompressed_data = Vec::new(); 31 | decoder.read_to_end(&mut decompressed_data)?; 32 | 33 | // Deserialize the message from CBOR format 34 | let message = serde_cbor::from_slice(&decompressed_data)?; 35 | 36 | Ok(message) 37 | } 38 | -------------------------------------------------------------------------------- /SQUICD/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod common; 2 | pub mod dsl; 3 | -------------------------------------------------------------------------------- /SQUICD/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::thread; 2 | use std::time::Duration; 3 | 4 | use SQUICD::common::Message; 5 | use SQUICD::dsl::Squicd; 6 | 7 | fn main() -> ! { 8 | thread::spawn(move || { 9 | run_server(); 10 | }); 11 | run_client(); 12 | loop { 13 | std::thread::park(); 14 | } 15 | } 16 | 17 | fn run_server() { 18 | Squicd::with_handler( 19 | |message| { 20 | println!("Received message: {:?}", message); 21 | thread::sleep(Duration::from_secs(1)); 22 | let new_message = Message { 23 | id: message.id + 1, 24 | content: message.content.clone(), 25 | timestamp: message.timestamp, 26 | }; 27 | //Send message to next service. 28 | if let Err(e) = Squicd::send_message("127.0.0.1:4433", new_message) { 29 | eprintln!("Error sending message: {:?}", e); 30 | } 31 | }) 32 | .with_error_handler( 33 | |err| { 34 | println!("Side-effect handle: {:?}", err); 35 | }) 36 | .with_cert("cert.crt") 37 | .with_key("cert.key") 38 | .with_port("4433") 39 | .start(); 40 | } 41 | 42 | fn run_client() { 43 | let message = Message { 44 | id: 1, 45 | content: "Hello, Squicd!".to_string(), 46 | timestamp: 1234567890, 47 | }; 48 | 49 | if let Err(e) = Squicd::send_message("127.0.0.1:4433", message) { 50 | eprintln!("Error sending message: {:?}", e); 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /actix/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "FunctionalRust" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | actix-web = "4" 10 | actix-files = "0.6.2" -------------------------------------------------------------------------------- /actix/actix.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /actix/src/actix_server.rs: -------------------------------------------------------------------------------- 1 | use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder, HttpRequest}; 2 | use actix_web::http::header::HeaderValue; 3 | 4 | /** 5 | Those tags inform [actix] framework about the [method] and [endpoint] 6 | Any endpoint is able to receive [HttpRequest] which contains all information about the 7 | request (Method, Uri, headers..) 8 | */ 9 | #[get("/hello")] 10 | async fn hello(req: HttpRequest) -> impl Responder { 11 | match req.headers().get("hello_header") { 12 | None => HttpResponse::Ok().body("Hello world!"), 13 | Some(header_value) => match header_value.to_str().ok() { 14 | Some(_) => HttpResponse::Ok().body("Hello world! with header"), 15 | None => HttpResponse::Ok().body("Hello world!") 16 | } 17 | } 18 | } 19 | 20 | /** 21 | In case of [POST/PUT] request, the endpoint can mark that expect to receive a [req_body] in [String] 22 | format to internally it can deserialize into String. 23 | */ 24 | #[post("/hello_body")] 25 | async fn hello_with_body(req_body: String) -> impl Responder { 26 | HttpResponse::Ok().body(req_body) 27 | } 28 | 29 | async fn manual_routing() -> impl Responder { 30 | HttpResponse::Ok().body("Hey there!") 31 | } 32 | 33 | /** 34 | Actix framework allow to build Http Server that by default accept Http 1/2 protocols. 35 | Using builder [HttpServer] we are to run he server passing: 36 | * [App] which is created using a builder, and for that App, we can: 37 | ** [route] traffic specifying the details of routing, with [path] and method [web::get::post:put::delete] 38 | ** [service] which use [meta-data tags] in the function to specify all the request details. 39 | 40 | Once we have the [HttpServer] we can [bind] an ip and port and [run] 41 | 42 | */ 43 | pub async fn run_server() -> std::io::Result<()> { 44 | HttpServer::new(|| { 45 | App::new() 46 | .route("/hello_routing", web::get().to(manual_routing)) 47 | .service(hello) 48 | .service(hello_with_body) 49 | }) 50 | .bind(("127.0.0.1", 8080))? 51 | .run() 52 | .await 53 | } -------------------------------------------------------------------------------- /actix/src/actix_web_server.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | use actix_files::NamedFile; 3 | use actix_web::{web, App, HttpServer}; 4 | use actix_web::{HttpRequest, Result}; 5 | 6 | 7 | /** 8 | * We use [parse] to search for the resource and we return a [PathBuf] 9 | * we use [NamedFile::open] feature to open unwrap the [Result], and return a [Result] 10 | which actix framework will use to render that static file. 11 | */ 12 | async fn index(_req: HttpRequest) -> Result { 13 | let path: PathBuf = "./static/index.html".parse().unwrap(); 14 | Ok(NamedFile::open(path)?) 15 | } 16 | 17 | /** 18 | We cover in [actix_server] how actix server is configured and running. 19 | In here just to add, using [web::scope] we can specify the path where this server is 20 | listening. In this case we listen from endpoint [/app] 21 | */ 22 | pub async fn run_server() -> std::io::Result<()> { 23 | HttpServer::new(|| { 24 | App::new().service( 25 | web::scope("/app") 26 | .route("/", web::get().to(index)), 27 | ) 28 | }) 29 | .bind(("127.0.0.1", 8080))? 30 | .run() 31 | .await 32 | } -------------------------------------------------------------------------------- /actix/src/main.rs: -------------------------------------------------------------------------------- 1 | mod actix_server; 2 | mod actix_web_server; 3 | 4 | #[actix_web::main] 5 | async fn main() -> std::io::Result<()> { 6 | // actix_server::run_server().await 7 | actix_web_server::run_server().await 8 | 9 | } 10 | -------------------------------------------------------------------------------- /actix/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |

Politrons Actix Web Page

6 | 7 | 8 | 9 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /actor_model/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "actor_model" 3 | version = "0.1.0" 4 | edition = "2024" 5 | 6 | [dependencies] 7 | tokio = { version = "1", features = ["full"] } 8 | serde = { version = "1.0", features = ["derive"] } 9 | bincode = "1.3" 10 | uuid = { version = "1.16.0", features = ["v4", "serde"] } 11 | 12 | 13 | -------------------------------------------------------------------------------- /ai_api_integration/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ai_api_integration" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | wasm-bindgen = { version = "0.2.84", features = ["serde-serialize"] } 8 | wasm-bindgen-futures = "0.4.43" 9 | serde = { version = "1.0.209", features = ["derive"] } 10 | serde_json = "1.0.127" 11 | web-sys = { version = "0.3.70", features = ["Window", "Request", "Response", "RequestInit", "RequestMode","Headers", "console"] } 12 | 13 | [lib] 14 | crate-type = ["cdylib", "rlib"] 15 | 16 | [profile.release] 17 | opt-level = "z" 18 | lto = true 19 | codegen-units = 1 20 | -------------------------------------------------------------------------------- /ai_api_integration/README.md: -------------------------------------------------------------------------------- 1 | # The Matrix AI - WASM + Rust + Google Gemini API 2 | 3 | Welcome to **The Matrix AI** project! This repository contains a Rust-based web server that interacts with Google's Gemini AI API to generate responses to user questions. The server is embedded in a web page using WebAssembly (WASM) to provide a seamless experience 4 | 5 | ## Project Overview 6 | 7 | This project leverages the power of Rust, WebAssembly (WASM), and Google's Gemini AI API to create an interactive web experience. Users can input a question and an API token, which the server uses to query the Gemini AI API and return a generated response. 8 | 9 | ## Features 10 | 11 | - **Rust-based Backend**: The backend is written in Rust and serves as a bridge between the web client and the Gemini AI API. 12 | - **WASM Integration**: The Rust code is compiled to WebAssembly, allowing it to run directly in the browser. 13 | - **Interactive Web Interface**: Users can input questions and their API token through a user-friendly web interface styled like "The Matrix" movie. 14 | - **Real-time AI Responses**: The system queries the Gemini AI API in real-time and displays the responses directly on the web page. 15 | 16 | ## Requirements 17 | 18 | Before you start, ensure you have the following installed: 19 | 20 | - **Rust**: The latest version of Rust, including the WASM target. 21 | - **Wasm-Pack**: A tool for building Rust-generated WebAssembly packages. 22 | 23 | ## Try yourself 24 | 25 | You can test how this service works hosted in my Github pages [Here](https://politrons.github.io/FunctionalRust/) 26 | 27 | In order to use the service, you will have to obtain a AIStudio API Key [Here](https://aistudio.google.com/app/apikey) 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /ai_api_integration/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | The Matrix AI 7 | 115 | 116 | 117 |
118 |

Welcome to The Matrix

119 |
120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 |
128 |

Response:

129 |

Your answer will appear here...

130 |
131 | 132 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /ai_api_integration/pkg/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | https://aistudio.google.com/app/apikey 4 | 5 | https://politrons.github.io/FunctionalRust/ -------------------------------------------------------------------------------- /ai_api_integration/pkg/ai_api_integration.d.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | /** 4 | * @param {string} api_key 5 | * @param {string} question 6 | * @returns {Promise} 7 | */ 8 | export function ask_question(api_key: string, question: string): Promise; 9 | 10 | export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; 11 | 12 | export interface InitOutput { 13 | readonly memory: WebAssembly.Memory; 14 | readonly ask_question: (a: number, b: number, c: number, d: number) => number; 15 | readonly __wbindgen_malloc: (a: number, b: number) => number; 16 | readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; 17 | readonly __wbindgen_export_2: WebAssembly.Table; 18 | readonly _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hd776ad9755cdf332: (a: number, b: number, c: number) => void; 19 | readonly __wbindgen_exn_store: (a: number) => void; 20 | readonly wasm_bindgen__convert__closures__invoke2_mut__h9de656cccec126bb: (a: number, b: number, c: number, d: number) => void; 21 | } 22 | 23 | export type SyncInitInput = BufferSource | WebAssembly.Module; 24 | /** 25 | * Instantiates the given `module`, which can either be bytes or 26 | * a precompiled `WebAssembly.Module`. 27 | * 28 | * @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated. 29 | * 30 | * @returns {InitOutput} 31 | */ 32 | export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput; 33 | 34 | /** 35 | * If `module_or_path` is {RequestInfo} or {URL}, makes a request and 36 | * for everything else, calls `WebAssembly.instantiate` directly. 37 | * 38 | * @param {{ module_or_path: InitInput | Promise }} module_or_path - Passing `InitInput` directly is deprecated. 39 | * 40 | * @returns {Promise} 41 | */ 42 | export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise } | InitInput | Promise): Promise; 43 | -------------------------------------------------------------------------------- /ai_api_integration/pkg/ai_api_integration_bg.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/politrons/FunctionalRust/1f7c9584800c8347ea7cacb7f0e486620d4c73ac/ai_api_integration/pkg/ai_api_integration_bg.wasm -------------------------------------------------------------------------------- /ai_api_integration/pkg/ai_api_integration_bg.wasm.d.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | export const memory: WebAssembly.Memory; 4 | export function ask_question(a: number, b: number, c: number, d: number): number; 5 | export function __wbindgen_malloc(a: number, b: number): number; 6 | export function __wbindgen_realloc(a: number, b: number, c: number, d: number): number; 7 | export const __wbindgen_export_2: WebAssembly.Table; 8 | export function _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hd776ad9755cdf332(a: number, b: number, c: number): void; 9 | export function __wbindgen_exn_store(a: number): void; 10 | export function wasm_bindgen__convert__closures__invoke2_mut__h9de656cccec126bb(a: number, b: number, c: number, d: number): void; 11 | -------------------------------------------------------------------------------- /ai_api_integration/pkg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ai_api_integration", 3 | "type": "module", 4 | "version": "0.1.0", 5 | "files": [ 6 | "ai_api_integration_bg.wasm", 7 | "ai_api_integration.js", 8 | "ai_api_integration.d.ts" 9 | ], 10 | "main": "ai_api_integration.js", 11 | "types": "ai_api_integration.d.ts", 12 | "sideEffects": [ 13 | "./snippets/*" 14 | ] 15 | } -------------------------------------------------------------------------------- /ai_api_integration/src/lib.rs: -------------------------------------------------------------------------------- 1 | use wasm_bindgen::prelude::*; 2 | use wasm_bindgen_futures::JsFuture; 3 | use web_sys::{Request, Response, RequestInit, Headers}; 4 | use serde::{Deserialize, Serialize}; 5 | use serde_json::{json, Value}; 6 | use wasm_bindgen::__rt::IntoJsResult; 7 | 8 | #[wasm_bindgen] 9 | pub async fn ask_question(api_key: String, question: String) -> Result { 10 | println!("Request received"); 11 | 12 | let model_url = format!( 13 | "https://generativelanguage.googleapis.com/v1/models/gemini-1.5-flash:generateContent?key={}", 14 | api_key 15 | ); 16 | 17 | let request_body = ModelRequest { 18 | contents: vec![Content { 19 | parts: vec![Part { text: question }], 20 | }], 21 | }; 22 | 23 | let request = create_request(&model_url, &request_body); 24 | let resp_value = make_http_request(&request).await; 25 | let response_json = transform_response_in_json(resp_value).await; 26 | let text = get_text_from_json(response_json); 27 | 28 | Ok(JsValue::from_str(&text)) 29 | } 30 | 31 | 32 | // Function to create an HTTP request 33 | fn create_request(model_url: &String, request_body: &ModelRequest) -> Request { 34 | // Serializes the request body to a JSON string 35 | let body = json!(request_body).to_string(); 36 | 37 | let request_init = RequestInit::new(); 38 | request_init.set_method("POST"); 39 | request_init.set_body(&JsValue::from_str(&body)); 40 | 41 | let headers = Headers::new().unwrap(); 42 | headers.set("Content-Type", "application/json").unwrap(); 43 | 44 | request_init.set_headers(&headers); 45 | 46 | // Creates and returns a new Request object with the specified URL and options 47 | let request = Request::new_with_str_and_init(&model_url, &request_init).unwrap(); 48 | request 49 | } 50 | 51 | // Function to send the HTTP request and receive the response 52 | async fn make_http_request(request: &Request) -> JsValue { 53 | // Gets the global Window object, which represents the browser window 54 | let window = web_sys::window().unwrap(); 55 | 56 | // Sends the request using the Fetch API to the Google Gemini AI API and waits for the response 57 | let resp_js_value = JsFuture::from(window.fetch_with_request(&request)).await.unwrap(); 58 | resp_js_value 59 | } 60 | 61 | // Function to convert the response to JSON 62 | async fn transform_response_in_json(resp_value: JsValue) -> Value { 63 | let resp: Response = resp_value.dyn_into().unwrap(); 64 | 65 | // Converts the Response object into a JavaScript Promise that resolves to a JSON object 66 | let json = JsFuture::from(resp.json().unwrap()).await.unwrap(); 67 | 68 | // Converts the JSON object from JsValue to a serde_json::Value for easier manipulation in Rust 69 | let response_json: Value = json.into_serde().unwrap(); 70 | response_json 71 | } 72 | 73 | // Function to extract the relevant text from the JSON response provided by the Google Gemini AI API 74 | fn get_text_from_json(response_json: Value) -> String { 75 | // Navigates through the JSON structure to extract the text response 76 | let text = response_json["candidates"] 77 | .get(0) 78 | .and_then(|candidate| candidate["content"]["parts"].get(0)) 79 | .and_then(|part| part["text"].as_str()) 80 | .unwrap_or("No response text found") 81 | .to_string(); 82 | text 83 | } 84 | 85 | // Data structures used to represent the request body sent to the Google Gemini AI API 86 | #[derive(Debug, Serialize, Deserialize)] 87 | struct Part { 88 | text: String, 89 | } 90 | 91 | #[derive(Debug, Serialize, Deserialize)] 92 | struct Content { 93 | parts: Vec, 94 | } 95 | 96 | #[derive(Debug, Serialize, Deserialize)] 97 | struct ModelRequest { 98 | contents: Vec, 99 | } 100 | -------------------------------------------------------------------------------- /architecture/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "architecture" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | -------------------------------------------------------------------------------- /architecture/src/main.rs: -------------------------------------------------------------------------------- 1 | mod circuit_breaker; 2 | 3 | fn main() { 4 | println!("Hello, world!"); 5 | } 6 | -------------------------------------------------------------------------------- /dragon_ball/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dragon_ball" 3 | version = "0.1.0" 4 | edition = "2021" 5 | description="Dragon ball Z Fight game" 6 | license="Apache-2.0" 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | bevy="0.11.0" 12 | bevy_audio = "0.11.0" 13 | rand = "0.8" 14 | lazy_static = "1.4.0" -------------------------------------------------------------------------------- /dragon_ball/README.md: -------------------------------------------------------------------------------- 1 | # Rust Dragon Ball Z 2 | 3 | Author Pablo Picouto Garcia 4 | 5 | Dragon Ball Z Fight Game Engine Using [Bevy](https://bevyengine.org) 6 | 7 | All used Sprites are coming from [spriters-resource](https://www.spriters-resource.com) 8 | 9 | You can also find the [crates.io](https://crates.io/crates/dragon_ball) 10 | 11 | 12 | https://github.com/politrons/FunctionalRust/assets/2054461/aa0b7a0c-687b-4866-9af5-d3742334af77 13 | 14 | 15 | https://github.com/politrons/FunctionalRust/assets/2054461/eef4da97-e9d4-4637-b642-77938e27cd48 16 | 17 | 18 | https://github.com/politrons/FunctionalRust/assets/2054461/d35eb1b5-d29e-48fb-90e2-069f040c4f73 19 | 20 | ## Players 21 | 22 | ![My image](assets/trunk_player.png) 23 | ![My image](assets/dr_hero_player.png) 24 | ![My image](assets/android_17_player.png) 25 | ![My image](assets/android_18_player.png) 26 | 27 | ## Sprites 28 | 29 | ![My image](assets/trunk.png) 30 | 31 | ![My image](assets/dr_hero.png) 32 | 33 | ![My image](assets/android_17.png) 34 | 35 | ![My image](assets/android_18.png) 36 | 37 | ## How to Play 38 | 39 | Clone the repo, and run ```Main``` class 40 | 41 | ## Keyboard 42 | 43 | ```<-``` Dodge. 44 | 45 | ```Space``` Attack. 46 | 47 | ```Enter``` Super Attack. 48 | 49 | ```S``` Super Saiyan mode. 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /dragon_ball/assets/android_17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/politrons/FunctionalRust/1f7c9584800c8347ea7cacb7f0e486620d4c73ac/dragon_ball/assets/android_17.png -------------------------------------------------------------------------------- /dragon_ball/assets/android_17_player.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/politrons/FunctionalRust/1f7c9584800c8347ea7cacb7f0e486620d4c73ac/dragon_ball/assets/android_17_player.png -------------------------------------------------------------------------------- /dragon_ball/assets/android_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/politrons/FunctionalRust/1f7c9584800c8347ea7cacb7f0e486620d4c73ac/dragon_ball/assets/android_18.png -------------------------------------------------------------------------------- /dragon_ball/assets/android_18_player.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/politrons/FunctionalRust/1f7c9584800c8347ea7cacb7f0e486620d4c73ac/dragon_ball/assets/android_18_player.png -------------------------------------------------------------------------------- /dragon_ball/assets/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/politrons/FunctionalRust/1f7c9584800c8347ea7cacb7f0e486620d4c73ac/dragon_ball/assets/background.png -------------------------------------------------------------------------------- /dragon_ball/assets/dbz.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/politrons/FunctionalRust/1f7c9584800c8347ea7cacb7f0e486620d4c73ac/dragon_ball/assets/dbz.ogg -------------------------------------------------------------------------------- /dragon_ball/assets/dr_hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/politrons/FunctionalRust/1f7c9584800c8347ea7cacb7f0e486620d4c73ac/dragon_ball/assets/dr_hero.png -------------------------------------------------------------------------------- /dragon_ball/assets/dr_hero_player.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/politrons/FunctionalRust/1f7c9584800c8347ea7cacb7f0e486620d4c73ac/dragon_ball/assets/dr_hero_player.png -------------------------------------------------------------------------------- /dragon_ball/assets/trunk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/politrons/FunctionalRust/1f7c9584800c8347ea7cacb7f0e486620d4c73ac/dragon_ball/assets/trunk.png -------------------------------------------------------------------------------- /dragon_ball/assets/trunk_b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/politrons/FunctionalRust/1f7c9584800c8347ea7cacb7f0e486620d4c73ac/dragon_ball/assets/trunk_b.png -------------------------------------------------------------------------------- /dragon_ball/assets/trunk_player.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/politrons/FunctionalRust/1f7c9584800c8347ea7cacb7f0e486620d4c73ac/dragon_ball/assets/trunk_player.png -------------------------------------------------------------------------------- /dynamic_loading/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dynamic_loading" 3 | version = "0.1.0" 4 | edition = "2021" 5 | default-libraries = false 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | libloading="0.8.0" 11 | dynamic_loading_contract={ version = "0.1.0", path = "../dynamic_loading_contract" } 12 | -------------------------------------------------------------------------------- /dynamic_loading/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate libloading; 2 | 3 | use libloading::{Library, Symbol}; 4 | use dynamic_loading_contract::PluginTrait; 5 | 6 | /// Using [libloading] library we're able to load Trait implementations in runtime, without have to know the specific type 7 | /// that implement the trait, allowing same pattern than in Java Service Provider Interface(SPI). 8 | /// This allow inject in a program different implementations just adding the path of the [.dylib] file that contains 9 | /// the implementation, and knowing the name of the [symbol] created in that library. 10 | /// 11 | /// [Library::new] oad the shared object file 12 | /// [lib.get(b"your_symbol_name\0")] Use a symbol from the shared object file and return a [Symbol] function type 13 | /// [plugin_symbol_func()] we run the function so we get the dynamic object Box 14 | /// [plugin.hello_world()] we run the action 15 | /// The shared object file is unloaded automatically when 'lib' goes out of scope 16 | fn main() { 17 | unsafe { 18 | let shared_obj_lib = Library::new("../dynamic_loading_plugin/target/release/libdynamic_loading_plugin.dylib").unwrap(); 19 | let plugin_symbol_func: Symbol Box> = shared_obj_lib.get(b"create_plugin\0").unwrap(); 20 | let plugin = plugin_symbol_func(); 21 | plugin.hello_world(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /dynamic_loading_contract/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dynamic_loading_contract" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /dynamic_loading_contract/src/lib.rs: -------------------------------------------------------------------------------- 1 | ///The trait contract to be used by the [plugin] to create the implementation, 2 | /// and by the [dynamic_loading] cargo to load in runtime any implementation of this contract 3 | pub trait PluginTrait { 4 | fn hello_world(&self); 5 | } 6 | 7 | -------------------------------------------------------------------------------- /dynamic_loading_plugin/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dynamic_loading_plugin" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [lib] 7 | crate-type = ["cdylib"] 8 | 9 | [dependencies] 10 | dynamic_loading_contract={ version = "0.1.0", path = "../dynamic_loading_contract" } -------------------------------------------------------------------------------- /dynamic_loading_plugin/src/lib.rs: -------------------------------------------------------------------------------- 1 | use dynamic_loading_contract::{PluginTrait}; 2 | 3 | /// In order to create a dynamic library that can be used in runtime discovery we need to use 4 | /// crate-type = ["cdylib"] in our [Cargo.toml] file. Then it will create a .[dylib] extension file 5 | 6 | pub struct PluginImplementation; 7 | 8 | ///Implementation of the contract [X] defined as an external dependency, we share with [dynamic_loading] cargo. 9 | impl PluginTrait for PluginImplementation { 10 | fn hello_world(&self) { 11 | println!("Plugin Hello world implementation"); 12 | } 13 | } 14 | 15 | ///For this patter, we use "dynamic objects", which typically refers to objects whose types 16 | /// are not known at compile time and can vary at runtime. 17 | /// The [Box] it will expose all functions defined in the [Trait]. 18 | /// Use [pub extern "C"] is mandatory to create a reference that can be used by consumer of this library, 19 | /// to discover the function in runtime loading. 20 | #[no_mangle] 21 | pub extern "C" fn create_plugin() -> Box { 22 | Box::new(PluginImplementation { }) 23 | } 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /game_3d/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "game_3d" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | bevy="0.11.0" 10 | bevy_audio = "0.11.0" 11 | rand = "0.8" 12 | lazy_static = "1.4.0" 13 | bevy_third_person_camera = "0.1.5" -------------------------------------------------------------------------------- /game_3d/src/board.rs: -------------------------------------------------------------------------------- 1 | use bevy::prelude::*; 2 | 3 | pub struct BoardPlugin; 4 | 5 | impl Plugin for BoardPlugin { 6 | 7 | fn build(&self, app: &mut App){ 8 | app.add_systems(Startup, spawn_board); 9 | } 10 | } 11 | 12 | fn spawn_board( 13 | mut command: Commands, 14 | mut mesh: ResMut>, 15 | mut materials: ResMut>) { 16 | let board = PbrBundle { 17 | mesh: mesh.add(Mesh::from(shape::Plane::from_size(15.0))), 18 | material: materials.add(Color::DARK_GREEN.into()), 19 | ..default() 20 | }; 21 | command.spawn(board); 22 | } -------------------------------------------------------------------------------- /game_3d/src/director.rs: -------------------------------------------------------------------------------- 1 | use bevy::prelude::*; 2 | use bevy_third_person_camera::*; 3 | 4 | pub struct DirectorPlugin; 5 | 6 | impl Plugin for DirectorPlugin { 7 | 8 | fn build(&self, app: &mut App){ 9 | app.add_systems(Startup, (spawn_camera, spawn_light)); 10 | } 11 | } 12 | 13 | 14 | fn spawn_camera(mut command: Commands) { 15 | let camera = (Camera3dBundle { 16 | transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y), 17 | ..default() 18 | }, ThirdPersonCamera::default()); 19 | command.spawn(camera); 20 | } 21 | 22 | fn spawn_light(mut command: Commands) { 23 | let light = PointLightBundle { 24 | point_light: PointLight { 25 | intensity: 2000.0, 26 | ..default() 27 | }, 28 | transform: Transform::from_xyz(0.0, 5.0, 0.0), 29 | ..default() 30 | }; 31 | command.spawn(light); 32 | } 33 | -------------------------------------------------------------------------------- /game_3d/src/main.rs: -------------------------------------------------------------------------------- 1 | use bevy::prelude::*; 2 | use bevy::prelude::shape::Plane; 3 | use bevy_third_person_camera::*; 4 | 5 | mod player; 6 | mod board; 7 | mod director; 8 | 9 | use player::PlayerPlugin; 10 | use board::BoardPlugin; 11 | use director::DirectorPlugin; 12 | 13 | fn main() { 14 | App::new() 15 | .add_plugins((DefaultPlugins,PlayerPlugin,BoardPlugin,DirectorPlugin, ThirdPersonCameraPlugin)) 16 | .run() 17 | } 18 | 19 | 20 | -------------------------------------------------------------------------------- /game_3d/src/player.rs: -------------------------------------------------------------------------------- 1 | use bevy::prelude::*; 2 | use bevy_third_person_camera::*; 3 | 4 | pub struct PlayerPlugin; 5 | 6 | impl Plugin for PlayerPlugin { 7 | fn build(&self, app: &mut App) { 8 | app.add_systems(Startup, spawn_player) 9 | .add_systems(Update, movement); 10 | } 11 | } 12 | 13 | #[derive(Component)] 14 | struct Player; 15 | 16 | #[derive(Component)] 17 | struct Speed(f32); 18 | 19 | fn movement( 20 | input_keys: Res>, 21 | time: Res