From cdf2ad4c08bb46a95e2d59dee291e9deae0aa06d Mon Sep 17 00:00:00 2001 From: MMADUs Date: Wed, 16 Oct 2024 14:25:17 +0700 Subject: [PATCH 1/2] feat: enumeration and pattern matching --- .../src/lib.rs | 158 +++++++++++++++++- 1 file changed, 157 insertions(+), 1 deletion(-) diff --git a/basics/05_enumeration_dan_pattern_matching/src/lib.rs b/basics/05_enumeration_dan_pattern_matching/src/lib.rs index c4f0f4c..a65db30 100644 --- a/basics/05_enumeration_dan_pattern_matching/src/lib.rs +++ b/basics/05_enumeration_dan_pattern_matching/src/lib.rs @@ -1,6 +1,162 @@ #[cfg(test)] mod tests { + // basic pattern matching + #[test] + fn pattern_match() { + let kata = "bakso"; + // pattern matching string + match kata { + "bakso" => println!("bakso"), + "burger" => println!("burger"), + _ => println!("pilihan selain di atas"), + } + + let angka = 100; + // pattern matching angka, bisa integer, float, dll + match angka { + 100 => println!("ini angka 100"), + 200 => println!("ini angka 200"), + _ => println!("pilihan selain di atas"), + } + + let boolean = true; + // pattern matching boolean + match boolean { + true => println!("ini true"), + false => println!("ini false"), + } + } + // setelah memahami pattern matching + // kita masuk ke enum type + enum Animal { + Dog, + Cat, + Fish + } + // penggunaan dasar enum + #[test] + fn basic_enum() { + // buat variable dengan enum type dog + let dog = Animal::Dog; + // pattern match enum + // masing masing pattern return string + let result = match dog { + Animal::Dog => "dog".to_string(), + Animal::Cat => "cat".to_string(), + Animal::Fish => "fish".to_string(), + }; + // cek jika return sesuai pattern match + assert_eq!(result, "dog"); + + let cat = Animal::Cat; + // pattern match cat + let result = match cat { + Animal::Dog => "dog".to_string(), + Animal::Cat => "cat".to_string(), + Animal::Fish => "fish".to_string(), + }; + // cek jika return sesuai pattern match + assert_eq!(result, "cat"); + let fish = Animal::Fish; + // pattern match cat + let result = match fish { + Animal::Dog => "dog".to_string(), + Animal::Cat => "cat".to_string(), + Animal::Fish => "fish".to_string(), + }; + // cek jika return sesuai pattern match + assert_eq!(result, "fish"); + } + // setelah memahami enum + // enum bisa menampung suatu nilai dengan type yang di tentukan + // ini bisa di sebut sebagai enum states + enum Person { + Budi(String), + Andi(String, i8), + Anton(String, i8, f64), + } + // penggunaan enum states #[test] - fn start() {} + fn enum_state() { + // deklarasi budi dengan enum states yang telah di definisikan + let budi = Person::Budi("polisi".to_string()); + // pattern match budi + let pekerjaan_budi = match budi { + Person::Budi(pekerjaan) => { + println!("pekerjaan budi adalah: {}", pekerjaan); + pekerjaan + }, + Person::Andi(pekerjaan, umur) => pekerjaan, + Person::Anton(pekerjaan, umur, gaji) => pekerjaan, + }; + // validasi pekerjaan budi + assert_eq!(pekerjaan_budi, "polisi"); + + // deklarasi andi dengan enum states yang telah di definisikan + let andi = Person::Andi("programmer".to_string(), 25); + // pattern match andi + let umur_andi = match andi { + Person::Andi(pekerjaan, umur) => { + println!("umur andi adalah: {}", umur); + umur + }, + Person::Anton(pekerjaan, umur, gaji) => umur, + _ => 0 + }; + // validasi umut andi + assert_eq!(umur_andi, 25); + + // deklarasi anton dengan enum states yang telah di definisikan + let anton = Person::Anton("dokter".to_string(), 30, 25000000.00); + // pattern match anton + let gaji_anton = match anton { + Person::Anton(pekerjaan, umur, gaji) => { + println!("gaji anton adalah: {}", gaji); + gaji + }, + _ => 0.0 + }; + // validasi gaji anton + assert_eq!(gaji_anton, 25000000.00); + } + // setelah memahami enum states + // kita bisa membuat enum method dan mengakses states tersebut + enum Tebakan { + Kalah(String), + Menang(String), + } + // deklarasi enum method di dalam keyword impl + impl Tebakan { + // method dari enum tebakan + fn tebak(&self) -> String { + match self { + Tebakan::Kalah(reason_kalah) => { + println!("Tebakan salah: {}", reason_kalah); + reason_kalah.to_string() + } + Tebakan::Menang(reason_menang) => { + println!("Tebakan benar: {}", reason_menang); + reason_menang.to_string() + } + } + } + } + // penggunaan enum method + #[test] + fn enum_method() { + // buatkan enum type kalah dengan alasan kalah sebagai enum state + let pilihan = Tebakan::Kalah("ini alasan tebakan mu salah".to_string()); + // panggile enum method + let alasan = pilihan.tebak(); + // validasi alasan + assert_eq!(alasan, "ini alasan tebakan mu salah"); + + // buatkan enum type menang dengan alasan menang sebagai enum state + let pilihan = Tebakan::Menang("ini alasan tebakan mu menang".to_string()); + // panggil enum method + let alasan = pilihan.tebak(); + // validasi alasan + assert_eq!(alasan, "ini alasan tebakan mu menang"); + } } From 866e42666cd2c7162fb86d2a06f13914589d866f Mon Sep 17 00:00:00 2001 From: MMADUs Date: Wed, 16 Oct 2024 23:45:35 +0700 Subject: [PATCH 2/2] fix: memisahkan example dari lib.rs --- .../src/example.rs | 155 ++++++++++++++++ .../src/lib.rs | 165 ++---------------- .../06_result_dan_option_type/src/example.rs | 114 ++++++++++++ basics/06_result_dan_option_type/src/lib.rs | 120 +------------ 4 files changed, 287 insertions(+), 267 deletions(-) create mode 100644 basics/05_enumeration_dan_pattern_matching/src/example.rs create mode 100644 basics/06_result_dan_option_type/src/example.rs diff --git a/basics/05_enumeration_dan_pattern_matching/src/example.rs b/basics/05_enumeration_dan_pattern_matching/src/example.rs new file mode 100644 index 0000000..77dbffe --- /dev/null +++ b/basics/05_enumeration_dan_pattern_matching/src/example.rs @@ -0,0 +1,155 @@ +pub fn pattern_match() { + let kata = "bakso"; + // pattern matching string + match kata { + "bakso" => println!("bakso"), + "burger" => println!("burger"), + _ => println!("pilihan selain di atas"), + } + + let angka = 100; + // pattern matching angka, bisa integer, float, dll + match angka { + 100 => println!("ini angka 100"), + 200 => println!("ini angka 200"), + _ => println!("pilihan selain di atas"), + } + + let boolean = true; + // pattern matching boolean + match boolean { + true => println!("ini true"), + false => println!("ini false"), + } +} +// setelah memahami pattern matching +// kita masuk ke enum type +enum Animal { + Dog, + Cat, + Fish +} +// penggunaan dasar enum +pub fn basic_enum() { + // buat variable dengan enum type dog + let dog = Animal::Dog; + // pattern match enum + // masing masing pattern return string + let result = match dog { + Animal::Dog => "dog".to_string(), + Animal::Cat => "cat".to_string(), + Animal::Fish => "fish".to_string(), + }; + // cek jika return sesuai pattern match + assert_eq!(result, "dog"); + + let cat = Animal::Cat; + // pattern match cat + let result = match cat { + Animal::Dog => "dog".to_string(), + Animal::Cat => "cat".to_string(), + Animal::Fish => "fish".to_string(), + }; + // cek jika return sesuai pattern match + assert_eq!(result, "cat"); + + let fish = Animal::Fish; + // pattern match cat + let result = match fish { + Animal::Dog => "dog".to_string(), + Animal::Cat => "cat".to_string(), + Animal::Fish => "fish".to_string(), + }; + // cek jika return sesuai pattern match + assert_eq!(result, "fish"); +} +// setelah memahami enum +// enum bisa menampung suatu nilai dengan type yang di tentukan +// ini bisa di sebut sebagai enum states +enum Person { + Budi(String), + Andi(String, i8), + Anton(String, i8, f64), +} +// penggunaan enum states +pub fn enum_state() { + // deklarasi budi dengan enum states yang telah di definisikan + let budi = Person::Budi("polisi".to_string()); + // pattern match budi + let pekerjaan_budi = match budi { + Person::Budi(pekerjaan) => { + println!("pekerjaan budi adalah: {}", pekerjaan); + pekerjaan + }, + Person::Andi(pekerjaan, umur) => pekerjaan, + Person::Anton(pekerjaan, umur, gaji) => pekerjaan, + }; + // validasi pekerjaan budi + assert_eq!(pekerjaan_budi, "polisi"); + + // deklarasi andi dengan enum states yang telah di definisikan + let andi = Person::Andi("programmer".to_string(), 25); + // pattern match andi + let umur_andi = match andi { + Person::Andi(pekerjaan, umur) => { + println!("umur andi adalah: {}", umur); + umur + }, + Person::Anton(pekerjaan, umur, gaji) => umur, + _ => 0 + }; + // validasi umut andi + assert_eq!(umur_andi, 25); + + // deklarasi anton dengan enum states yang telah di definisikan + let anton = Person::Anton("dokter".to_string(), 30, 25000000.00); + // pattern match anton + let gaji_anton = match anton { + Person::Anton(pekerjaan, umur, gaji) => { + println!("gaji anton adalah: {}", gaji); + gaji + }, + _ => 0.0 + }; + // validasi gaji anton + assert_eq!(gaji_anton, 25000000.00); +} +// setelah memahami enum states +// kita bisa membuat enum method dan mengakses states tersebut +enum Tebakan { + Kalah(String), + Menang(String), +} +// deklarasi enum method di dalam keyword impl +impl Tebakan { + // method dari enum tebakan + fn tebak(&self) -> String { + match self { + Tebakan::Kalah(reason_kalah) => { + println!("Tebakan salah: {}", reason_kalah); + reason_kalah.to_string() + } + Tebakan::Menang(reason_menang) => { + println!("Tebakan benar: {}", reason_menang); + reason_menang.to_string() + } + } + } +} +// penggunaan enum method +pub fn enum_method() { + // buatkan enum type kalah dengan alasan kalah sebagai enum state + let pilihan = Tebakan::Kalah("ini alasan tebakan mu salah".to_string()); + // panggile enum method + let alasan = pilihan.tebak(); + // validasi alasan + assert_eq!(alasan, "ini alasan tebakan mu salah"); + + // buatkan enum type menang dengan alasan menang sebagai enum state + let pilihan = Tebakan::Menang("ini alasan tebakan mu menang".to_string()); + // panggil enum method + let alasan = pilihan.tebak(); + // validasi alasan + assert_eq!(alasan, "ini alasan tebakan mu menang"); +} + diff --git a/basics/05_enumeration_dan_pattern_matching/src/lib.rs b/basics/05_enumeration_dan_pattern_matching/src/lib.rs index a65db30..76ad1d9 100644 --- a/basics/05_enumeration_dan_pattern_matching/src/lib.rs +++ b/basics/05_enumeration_dan_pattern_matching/src/lib.rs @@ -1,162 +1,17 @@ +mod example; + #[cfg(test)] mod tests { - // basic pattern matching - #[test] - fn pattern_match() { - let kata = "bakso"; - // pattern matching string - match kata { - "bakso" => println!("bakso"), - "burger" => println!("burger"), - _ => println!("pilihan selain di atas"), - } + use crate::example; - let angka = 100; - // pattern matching angka, bisa integer, float, dll - match angka { - 100 => println!("ini angka 100"), - 200 => println!("ini angka 200"), - _ => println!("pilihan selain di atas"), - } - - let boolean = true; - // pattern matching boolean - match boolean { - true => println!("ini true"), - false => println!("ini false"), - } - } - // setelah memahami pattern matching - // kita masuk ke enum type - enum Animal { - Dog, - Cat, - Fish - } - // penggunaan dasar enum #[test] - fn basic_enum() { - // buat variable dengan enum type dog - let dog = Animal::Dog; - // pattern match enum - // masing masing pattern return string - let result = match dog { - Animal::Dog => "dog".to_string(), - Animal::Cat => "cat".to_string(), - Animal::Fish => "fish".to_string(), - }; - // cek jika return sesuai pattern match - assert_eq!(result, "dog"); - - let cat = Animal::Cat; - // pattern match cat - let result = match cat { - Animal::Dog => "dog".to_string(), - Animal::Cat => "cat".to_string(), - Animal::Fish => "fish".to_string(), - }; - // cek jika return sesuai pattern match - assert_eq!(result, "cat"); - - let fish = Animal::Fish; - // pattern match cat - let result = match fish { - Animal::Dog => "dog".to_string(), - Animal::Cat => "cat".to_string(), - Animal::Fish => "fish".to_string(), - }; - // cek jika return sesuai pattern match - assert_eq!(result, "fish"); - } - // setelah memahami enum - // enum bisa menampung suatu nilai dengan type yang di tentukan - // ini bisa di sebut sebagai enum states - enum Person { - Budi(String), - Andi(String, i8), - Anton(String, i8, f64), + fn example_test() { + example::pattern_match(); + example::basic_enum(); + example::enum_state(); + example::enum_method(); } - // penggunaan enum states - #[test] - fn enum_state() { - // deklarasi budi dengan enum states yang telah di definisikan - let budi = Person::Budi("polisi".to_string()); - // pattern match budi - let pekerjaan_budi = match budi { - Person::Budi(pekerjaan) => { - println!("pekerjaan budi adalah: {}", pekerjaan); - pekerjaan - }, - Person::Andi(pekerjaan, umur) => pekerjaan, - Person::Anton(pekerjaan, umur, gaji) => pekerjaan, - }; - // validasi pekerjaan budi - assert_eq!(pekerjaan_budi, "polisi"); - - // deklarasi andi dengan enum states yang telah di definisikan - let andi = Person::Andi("programmer".to_string(), 25); - // pattern match andi - let umur_andi = match andi { - Person::Andi(pekerjaan, umur) => { - println!("umur andi adalah: {}", umur); - umur - }, - Person::Anton(pekerjaan, umur, gaji) => umur, - _ => 0 - }; - // validasi umut andi - assert_eq!(umur_andi, 25); - // deklarasi anton dengan enum states yang telah di definisikan - let anton = Person::Anton("dokter".to_string(), 30, 25000000.00); - // pattern match anton - let gaji_anton = match anton { - Person::Anton(pekerjaan, umur, gaji) => { - println!("gaji anton adalah: {}", gaji); - gaji - }, - _ => 0.0 - }; - // validasi gaji anton - assert_eq!(gaji_anton, 25000000.00); - } - // setelah memahami enum states - // kita bisa membuat enum method dan mengakses states tersebut - enum Tebakan { - Kalah(String), - Menang(String), - } - // deklarasi enum method di dalam keyword impl - impl Tebakan { - // method dari enum tebakan - fn tebak(&self) -> String { - match self { - Tebakan::Kalah(reason_kalah) => { - println!("Tebakan salah: {}", reason_kalah); - reason_kalah.to_string() - } - Tebakan::Menang(reason_menang) => { - println!("Tebakan benar: {}", reason_menang); - reason_menang.to_string() - } - } - } - } - // penggunaan enum method #[test] - fn enum_method() { - // buatkan enum type kalah dengan alasan kalah sebagai enum state - let pilihan = Tebakan::Kalah("ini alasan tebakan mu salah".to_string()); - // panggile enum method - let alasan = pilihan.tebak(); - // validasi alasan - assert_eq!(alasan, "ini alasan tebakan mu salah"); - - // buatkan enum type menang dengan alasan menang sebagai enum state - let pilihan = Tebakan::Menang("ini alasan tebakan mu menang".to_string()); - // panggil enum method - let alasan = pilihan.tebak(); - // validasi alasan - assert_eq!(alasan, "ini alasan tebakan mu menang"); - } -} + fn start() {} +} \ No newline at end of file diff --git a/basics/06_result_dan_option_type/src/example.rs b/basics/06_result_dan_option_type/src/example.rs new file mode 100644 index 0000000..6c920a8 --- /dev/null +++ b/basics/06_result_dan_option_type/src/example.rs @@ -0,0 +1,114 @@ +// untuk error handling di rust menggunakan result sebagai hasil dari suatu proses +// result memiliki 2 kondisi utama yaitu Ok = hasil, dan Err = error + +fn get_ok() -> Result { + // untuk mengembalikan hasil, dengan keyword Ok(value) + Ok("ini result".to_string()) +} + +fn get_err() -> Result { + // untuk mengembalikan error, dengan keyword Err(value) + Err("ini error".to_string()) +} + +pub fn result_types() { + // memanggil function untuk return result terlebih dahulu + let result = get_ok(); + // memastikan hasil yang di return Ok + assert!(result.is_ok()); + // simulasi Ok pattern matching untuk tipe data Result + match result { + Ok(result) => println!("Hasil Ok: {}", result), + Err(e) => println!("Hasil Err: {}", e), + } + + // sama seperti di atas, namun kali ini simulasi error + let error = get_err(); + // memastikan hasil yang di return Err + assert!(error.is_err()); + // simulasi Err pattern matching untuk tipe data Result + match error { + Ok(result) => println!("Hasil Ok: {}", result), + Err(e) => println!("Hasil Err: {}", e), + } + + // syntax function dengan pattern matching bisa di persingkat menjadi + match get_ok() { + Ok(result) => println!("Hasil dipersingkat Ok: {}", result), + Err(e) => println!("Hasil Err: {}", e), + } + + // syntax function dengan pattern matching bisa di persingkat menjadi + match get_ok() { + // disini kita bisa menambahkan wildcard (_) untuk mengabaikan hasil yang tidak digunakan + // namun ini tidak disarankan, lebih baik di match secara explicit + Ok(result) => println!("Hasil dengan wildcard Ok: {}", result), + _ => (), + } +} + +/// bahasa pemrograman rust tidak memiliki nilai Null atau Nil seperti bahasa lainnya +/// rust memiliki fitur option untuk mencegah null value yang berpotensi bug +/// option memiliki 2 kondisi utama yaitu Some = ada value, dan None = tidak ada value + +fn get_some() -> Option { + // Some di gunakan untuk mengembalikan Option dengan value + Some("hasil dengan value".to_string()) +} + +fn get_none() -> Option { + // None di gunakan untuk mengembalikan Option tanpa value + None +} + +pub fn option_types() { + // memanggil function untuk return option terlebih dahulu + let option = get_some(); + // memastikan return some value + assert!(option.is_some()); + // simulasi Some di pattern matching + match option { + Some(result) => println!("Hasil Some: {}", result), + None => println!("Hasil None"), + } + + // memanggil function untuk return option terlebih dahulu + let option = get_none(); + // memastikan return none value + assert!(option.is_none()); + // simulasi None di pattern matching + match option { + Some(result) => println!("Hasil Some: {}", result), + None => println!("Hasil None"), + } + + // persingkat pattern matching dengan function + match get_some() { + Some(result) => println!("Hasil persingkat Some: {}", result), + None => println!("Hasil None"), + } + + // kita bisa melakukan unwrap yaitu mengambil value di dalam type option ini + // cara ini tidak disarankan, karena juga function return none akan menyebabkan panic + let hasil_option = get_none(); + assert!(hasil_option.is_none()); + // kita bisa menggunakan default value, sangat disarankan sewaktu waktu hasil nya none, agar tidak panic + let hasil = hasil_option.unwrap_or("ini hasil default".to_string()); + // kode dibawah ini akan meyebabkan error, jangan unwrap begitu saja pada option! + // let hasil = hasil_option.unwrap(); + println!("Hasil unwrap dengan default: {}", hasil); + + let hasil_kondisi = get_some(); + // if ini akan jalan jika di temui value dari option tersebut + if let Some(result) = hasil_kondisi { + // variable result yand di deklarasi sebagai some hanya bisa di akses di dalam if block saja + println!("kondisi result true: {}", result); + } + + // bisa di persingkat & simulasi jika value adalah none + if let Some(result) = get_none() { + // ini tidak akan jalan karna false! + // variable result mengharapkan some value dari function, namun function mengembalikan none. + println!("kondisi None & false: {}", result); + } +} diff --git a/basics/06_result_dan_option_type/src/lib.rs b/basics/06_result_dan_option_type/src/lib.rs index 74202cc..6561b33 100644 --- a/basics/06_result_dan_option_type/src/lib.rs +++ b/basics/06_result_dan_option_type/src/lib.rs @@ -1,119 +1,15 @@ +mod example; + #[cfg(test)] mod tests { - // untuk error handling di rust menggunakan result sebagai hasil dari suatu proses - // result memiliki 2 kondisi utama yaitu Ok = hasil, dan Err = error - - fn get_ok() -> Result { - // untuk mengembalikan hasil, dengan keyword Ok(value) - Ok("ini result".to_string()) - } - - fn get_err() -> Result { - // untuk mengembalikan error, dengan keyword Err(value) - Err("ini error".to_string()) - } + use crate::example; #[test] - fn result_types() { - // memanggil function untuk return result terlebih dahulu - let result = get_ok(); - // memastikan hasil yang di return Ok - assert!(result.is_ok()); - // simulasi Ok pattern matching untuk tipe data Result - match result { - Ok(result) => println!("Hasil Ok: {}", result), - Err(e) => println!("Hasil Err: {}", e), - } - - // sama seperti di atas, namun kali ini simulasi error - let error = get_err(); - // memastikan hasil yang di return Err - assert!(error.is_err()); - // simulasi Err pattern matching untuk tipe data Result - match error { - Ok(result) => println!("Hasil Ok: {}", result), - Err(e) => println!("Hasil Err: {}", e), - } - - // syntax function dengan pattern matching bisa di persingkat menjadi - match get_ok() { - Ok(result) => println!("Hasil dipersingkat Ok: {}", result), - Err(e) => println!("Hasil Err: {}", e), - } - - // syntax function dengan pattern matching bisa di persingkat menjadi - match get_ok() { - // disini kita bisa menambahkan wildcard (_) untuk mengabaikan hasil yang tidak digunakan - // namun ini tidak disarankan, lebih baik di match secara explicit - Ok(result) => println!("Hasil dengan wildcard Ok: {}", result), - _ => (), - } - } - - /// bahasa pemrograman rust tidak memiliki nilai Null atau Nil seperti bahasa lainnya - /// rust memiliki fitur option untuk mencegah null value yang berpotensi bug - /// option memiliki 2 kondisi utama yaitu Some = ada value, dan None = tidak ada value - - fn get_some() -> Option { - // Some di gunakan untuk mengembalikan Option dengan value - Some("hasil dengan value".to_string()) - } - - fn get_none() -> Option { - // None di gunakan untuk mengembalikan Option tanpa value - None + fn example_test() { + example::result_types(); + example::option_types(); } #[test] - fn option_types() { - // memanggil function untuk return option terlebih dahulu - let option = get_some(); - // memastikan return some value - assert!(option.is_some()); - // simulasi Some di pattern matching - match option { - Some(result) => println!("Hasil Some: {}", result), - None => println!("Hasil None"), - } - - // memanggil function untuk return option terlebih dahulu - let option = get_none(); - // memastikan return none value - assert!(option.is_none()); - // simulasi None di pattern matching - match option { - Some(result) => println!("Hasil Some: {}", result), - None => println!("Hasil None"), - } - - // persingkat pattern matching dengan function - match get_some() { - Some(result) => println!("Hasil persingkat Some: {}", result), - None => println!("Hasil None"), - } - - // kita bisa melakukan unwrap yaitu mengambil value di dalam type option ini - // cara ini tidak disarankan, karena juga function return none akan menyebabkan panic - let hasil_option = get_none(); - assert!(hasil_option.is_none()); - // kita bisa menggunakan default value, sangat disarankan sewaktu waktu hasil nya none, agar tidak panic - let hasil = hasil_option.unwrap_or("ini hasil default".to_string()); - // kode dibawah ini akan meyebabkan error, jangan unwrap begitu saja pada option! - // let hasil = hasil_option.unwrap(); - println!("Hasil unwrap dengan default: {}", hasil); - - let hasil_kondisi = get_some(); - // if ini akan jalan jika di temui value dari option tersebut - if let Some(result) = hasil_kondisi { - // variable result yand di deklarasi sebagai some hanya bisa di akses di dalam if block saja - println!("kondisi result true: {}", result); - } - - // bisa di persingkat & simulasi jika value adalah none - if let Some(result) = get_none() { - // ini tidak akan jalan karna false! - // variable result mengharapkan some value dari function, namun function mengembalikan none. - println!("kondisi None & false: {}", result); - } - } -} + fn start() {} +} \ No newline at end of file