{"id":16927430,"url":"https://github.com/snowsignal/cascade","last_synced_at":"2025-12-12T15:41:29.242Z","repository":{"id":57541630,"uuid":"144601257","full_name":"snowsignal/cascade","owner":"snowsignal","description":"Cascade expressions in Rust, inspired by Dart","archived":false,"fork":false,"pushed_at":"2024-04-22T17:55:02.000Z","size":29,"stargazers_count":119,"open_issues_count":1,"forks_count":2,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-01-19T06:30:21.865Z","etag":null,"topics":["cascade-expressions","hacktoberfest","macro","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/snowsignal.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-08-13T15:49:40.000Z","updated_at":"2025-01-18T02:51:13.000Z","dependencies_parsed_at":"2024-02-23T18:03:49.438Z","dependency_job_id":"5e517391-a948-4bb8-8ede-74929ad977a5","html_url":"https://github.com/snowsignal/cascade","commit_stats":null,"previous_names":["inquisitivepenguin/cascade"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snowsignal%2Fcascade","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snowsignal%2Fcascade/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snowsignal%2Fcascade/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/snowsignal%2Fcascade/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/snowsignal","download_url":"https://codeload.github.com/snowsignal/cascade/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235600038,"owners_count":19016195,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cascade-expressions","hacktoberfest","macro","rust"],"created_at":"2024-10-13T20:34:13.896Z","updated_at":"2025-10-07T07:30:45.693Z","avatar_url":"https://github.com/snowsignal.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `cascade`: Cascade expressions in Rust!\n`cascade` is a macro library for Rust that makes it easy and ergonomic\nto use cascade-like expressions, similar to Dart.\n\n```rust\n#[macro_use]\nextern crate cascade;\n\nfn main() {\n    let cascaded_list = cascade! {\n      Vec::new();\n      ..push(\"Cascades\");\n      ..push(\"reduce\");\n      ..push(\"boilerplate\");\n    };\n    println!(\"{:?}\", cascaded_list); // Will print '[\"Cascades\", \"reduce\", \"boilerplate\"]'\n}\n```\n\nThis is only a small example of what `cascade` lets you do:\nthe `basic_cascades` example in this repository covers the other\ncool features of the `cascade!` macro.\n\n#### Why does this need to exist?\nCascades reduce boilerplate by eliminating the need for a 'temporary'\nvariable when making several method calls in a row, and it also\nhelps make struct member assignments look more ergonomic. For\nexample:\n```rust\n#[macro_use]\nextern crate cascade;\n\n#[derive(Clone, Debug)]\nstruct Person {\n  pub name: String,\n  pub age: u32,\n  pub height: u32,\n  pub friend_names: Vec\u003cString\u003e\n}\n\nfn main() {\n    // Without cascades\n    let person = Person {\n      name: \"John Smith\",\n      age: 17,\n      height: 68, // 5' 8\"\n      friend_names: {\n        let mut tmp_names = Vec::new();\n        tmp_names.push(\"James Smith\".to_string());\n        tmp_names.push(\"Bob Jones\".to_string());\n        tmp_names.push(\"Billy Jones\".to_string());\n        tmp_names\n      }\n    };\n    // With cascades\n    let person = Person {\n      name: \"John Smith\",\n      age: 17,\n      height: 68,\n      friend_names: cascade! {\n        Vec::new();\n        ..push(\"James Smith\".to_string());\n        ..push(\"Bob Jones\".to_string());\n        ..push(\"Billy Jones\".to_string());\n      }\n    };\n    // Cascades also let you do cool stuff like this\n    let person_one_year_later = cascade! {\n      person;\n      ..age += 1;\n      ..height += 2;\n    };\n}\n```\n\nIn addition, cascades make it easier to design fluent interfaces.\nNo more returning `self` with every single function!\n\n### Changelog\n**1.0.0**: `cascade` has reached 1.0! Here are some of the cool new features and syntax\nchanges made as a part of this:\n- The syntax for binding variables has been changed to use `let` syntax. This makes it more\nin-line with Rust syntax and also allows you to specify the type of a cascaded expression.\n```rust\ncascade! {\n    // If you don't need to bind the statement to an identifier, you can use _\n    let _: Vec\u003cu32\u003e = vec![1,2,3].into_iter().map(|x| x + 1).collect();\n    ..push(1);\n}\n```\n- Statements no longer need `|` in front of them. You can just put the statement right in there, no prefix needed.\n- You can return expressions from cascades, just like normal Rust blocks. By default,\ncascades will already return the value of the cascaded variable. But if you want to return\na custom expression, you can put it at the end of a cascade block, with no semicolon.\n```rust\nlet has_more_than_three_elements = cascade! {\n    let v = vec![1,2,3];\n    ..push(4);\n    v.len() \u003e 3\n};\nprintln!(\"{}\", cascade! {\n    vec![1,2,3];\n    ..push(4);\n    ..into_iter().fold(0, |acc, x| acc + x)\n});\n```\n- Finally, you can have nested blocks within a cascade block. For example:\n```rust\ncascade! {\n    vec![1,2,3];\n    {\n        let a = 1;\n        ..push(a);\n    };\n}\n```\n\nI hope you enjoy cascade `1.0`! Remember to leave any complaints or suggestions\non [the issue tracker](https://github.com/InquisitivePenguin/cascade/issues).\n\n**0.1.3**: The ? operator now works with cascades, for scenarios like this:\n```rust\nfn file_read() -\u003e Result\u003cSomeFileClass, ErrorMsg\u003e {\n    cascade! {\n      SomeFileClass::create_file_reader(\"test.txt\");\n      ..load()?;\n      ..check_validity()?;\n    }\n}\n```\n\n**0.1.2**: You can now chain methods together, like this:\n```rust\nfn chain_example() {\n  cascade! {\n    FnChainTest::new();\n    ..chain().chain().chain();\n  }\n}\n```\n\n### Credits\nWritten by Jane Lewis\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnowsignal%2Fcascade","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsnowsignal%2Fcascade","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsnowsignal%2Fcascade/lists"}