{"id":18638246,"url":"https://github.com/dehasi/zeliba","last_synced_at":"2026-03-03T20:04:25.173Z","repository":{"id":44547407,"uuid":"240112263","full_name":"dehasi/zeliba","owner":"dehasi","description":"A handy DSL-ish library to make comparisons more readable.","archived":false,"fork":false,"pushed_at":"2025-05-22T22:09:36.000Z","size":91,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-13T08:42:21.965Z","etag":null,"topics":["fluent-api","fluent-checks","java-8","pattern-matching"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dehasi.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-02-12T20:49:35.000Z","updated_at":"2025-05-22T22:09:39.000Z","dependencies_parsed_at":"2025-09-13T08:28:15.617Z","dependency_job_id":"48137ec9-fa19-436c-921b-0213db7016da","html_url":"https://github.com/dehasi/zeliba","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/dehasi/zeliba","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dehasi%2Fzeliba","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dehasi%2Fzeliba/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dehasi%2Fzeliba/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dehasi%2Fzeliba/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dehasi","download_url":"https://codeload.github.com/dehasi/zeliba/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dehasi%2Fzeliba/sbom","scorecard":{"id":332665,"data":{"date":"2025-08-11","repo":{"name":"github.com/dehasi/zeliba","commit":"f6eed9254b18784fcec6dc30f948dd00bd88906d"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.2,"checks":[{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":1,"reason":"2 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 21 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T03:57:55.032Z","repository_id":44547407,"created_at":"2025-08-18T03:57:55.032Z","updated_at":"2025-08-18T03:57:55.032Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30057649,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-03T18:21:05.932Z","status":"ssl_error","status_checked_at":"2026-03-03T18:20:59.341Z","response_time":61,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["fluent-api","fluent-checks","java-8","pattern-matching"],"created_at":"2024-11-07T05:40:04.361Z","updated_at":"2026-03-03T20:04:25.137Z","avatar_url":"https://github.com/dehasi.png","language":"Java","readme":"# ZeLiba (The library)\n\nA handy DSL-ish helper to make the comparison more readable.\n\n[![Build Status](https://www.travis-ci.org/dehasi/zeliba.svg?branch=master)](https://www.travis-ci.org/dehasi/zeliba)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/me.dehasi/zeliba/badge.svg)](https://maven-badges.herokuapp.com/maven-central/me.dehasi/zeliba)\n[![Test Coverage](https://img.shields.io/codecov/c/github/dehasi/zeliba/master)](https://codecov.io/github/dehasi/zeliba?branch=master)\n![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/dehasi/zeliba)\n\nZeliba provides a fluent API to write a comparison (for `Comparable\u003cT\u003e`) and does other checks.\n\nInspired by [AssertJ](https://joel-costigliola.github.io/assertj/), [kotlin](https://kotlinlang.org/), [ZE FISH](https://vk.com/zefish)\n\n- [Motivation](#Motivation)\n- [Examples](#Examples)\n  - [TheComparable](#TheComparable)\n  - [TheChronoLocalDate](#TheChronoLocalDate)\n  - [TheChronoLocalDateTime](#TheChronoLocalDateTime)\n  - [TheObject](#TheObject)\n  - [TheString](#TheString)\n    - [isEmpty](#isEmpty)/[isBlank](#isBlank)\n    - [substring](#substring)\n    - [replaceAt](#replaceAt)\n  - [TheCollection](#TheCollection)\n  - [TheMap](#TheMap)\n    - [contains](#contains)\n    - [Optional get](#Optional-get)\n  - [When](#When)\n    - [is](#is)\n    - [isNot](#isNot)\n    - [and](#and)\n    - [or](#or)\n    - [then](#then)\n    - [orElse](#orElse)\n    - [orElseThrow](#orElseThrow)\n    - [asOptional](#asOptional)\n    - [Complex example](#Complex-example)\n  - [When2](#When2)\n- [License](#License)\n- [Installation](#Installation)\n  - [Maven](#Maven)\n  - [Gradle](#Gradle)\n- [Contribution](#Contribution)\n\n## Motivation\nZeliba main points are the following:\n* Provide a fluent API to write a comparison (for `Comparable\u003cT\u003e`)\n* Make `if`-checks better align with English grammar\n* Provide pattern matching for `Java 8`\n\n### Fluent compatible  \nJava doesn't support operator overloading, you can’t write something like `a \u003e b` for objects,\nas an alternative you can use  `Comparable\u003cT\u003e`. It makes its job, but it is not very convenient to use.   \nLook  `a.compareTo(b) \u003e ??`.\nEvery time you need to make small calculations in your head. It’s better (from readability POV) \nto write `a.isGreatherThan(b)`. Zeliba gives you the ability to do it.  \nSee examples [TheComparable](#TheComparable), [TheChronoLocalDate](#TheChronoLocalDate), [TheChonoDateTime](#TheChonoDateTime)\n\n### Better English  \nUsually, util methods start with `is` prefix (like `isEmpty`), but negations are covered via exclamation mark `!is`, \nwhich also makes you do calculations. I.e. “if a collection is empty” transforms into \n`collection.isEmpty()`, but “if a collection is *not* empty” transforms into `!collection.isEmpty()` \nwhich is read as “not the collection is empty”. It is obviously grammatically incorrect. \nUtil methods like `if(isNotEmpty(collection))` do a great job but still remain grammatically incorrect.\n We don’t say “if is not an empty collection”. \n Zeliba provides the same methods but also gives you a fluent API to write grammatically correct\n  code.  \nSee examples. [TheObject](#TheObject), [TheCollection](#TheCollection), [TheMap](#TheMap)\n\n### Pattern matching\nInspired by [when](https://kotlinlang.org/docs/reference/control-flow.html#when-expression) from `Kotlin`.  \nSince [Java 12](https://openjdk.java.net/jeps/325) `case`-expressions were extended. But `Java 8` is still\nwidely used and it's nice to have some fluent API which is more useful than `case` for pattern matching.\nZeliba provides some pattern-matching features.  \nSee [When](#When)\n\n## Examples\n\nThe examples reflect the master branch.\n\n### TheComparable\n\nLet's assume we have two comparable objects.\n```java\nBigDecimal val1 = ...\nBigDecimal val2 = ...\n```\n\nUsually we check `val1 \u003e val2` like `if (val1.compareTo(val2) \u003e 0)`\n\nBut with `TheComparable` it's much easier to read\n\n```java\nif (the(val1).isGreaterThan(val2)) {\n    ...\n}\n\nif (the(val2).isLessThan(val1)) {\n    ...\n}\n```\n\n\nFluent interval checks \n\n`val1 \u003c= value \u003c= val2`\n\n```java\nif (the(value).isInTheInterval().fromIncluded(val1).toIncluded(val2)) {\n    //...\n}\n```\n\n`val1 \u003c value \u003c val2`\n\n```java\nif (the(value).isInTheInterval().fromExcluded(val1).toExcluded(val2)) {\n    //...\n}\n```\n\n\n`val1 \u003c value \u003c= val2`\n\n```java\nif (the(value).isInTheInterval().fromExcluded(val1).toIncluded(val2)) {\n    //...\n}\n```\n\n### TheChronoLocalDate\n   \nAlso, there are extensions to compare dates\n   \n   ```java\nLocalDate someDate = ...\nLocalDate otherDate = ...\n\nif (the(otherDate).isAfterOrEqual(someDate)) {\n    ...\n}\n   \nif (the(someDate).isNotAfter(otherDate)) {\n    ...\n}\n\nif (the(otherDate).isBeforeOrEqual(someDate)) {\n    ...\n}\n   \nif (the(someDate).isNotBefore(otherDate)) {\n    ...\n}\n   ```\n   \n### TheChronoLocalDateTime\n\nThe same for `DateTime`\n\n```java\nLocalDateTime someDateTime = ...\nLocalDateTime otherDateTime = ...\n\nif (the(otherDate).isAfterOrEqual(someDateTime)) {\n    ...\n}\n\nif (the(someDate).isNotAfter(otherDateTime)) {\n    ...\n}\n\nif (the(otherDate).isBeforeOrEqual(someDateTime)) {\n    ...\n}\n\nif (the(someDate).isNotBefore(otherDateTime)) {\n    ...\n}\n```\n\n### TheObject\n\nFluent null and not equals checks\n\n```java\nObject someObject = ...\nObject otherObject = ...\n\nif (the(otherObject).isNotEqualTo(someObject)) {\n    ...\n}\n\nif (the(someObject).isNotNull()) {\n    ...\n}\n\nif (the(someObject).isNull()) {\n    ...\n}\n```\n\n### TheString\n\nFluent checks for empty/blank + avoiding `NPE`\n\n#### isEmpty\n```Java\nString str1 = null;\nString str2 = \"abcd\";\n\nif (the(str1).isEmpty()) { ... } // returns false\nif (the(str2).isNotEmpty()) { ... } // returns true\n```\n\n#### isBlank\n```Java\nString str1 = null;\nString str2 = \"abcd\";\n\nif (the(str1).isBlank()) { ... } // returns true\nif (the(str2).isNotBlank()) { ... } // returns false\n```\n\n#### substring\nMax possible substring\n\n```java\nString str = \"abcd\"\n\nString s = the(str).substring(2, 50); // returns \"cd\"\nString s = the(str).substring(-2, 2); // returns \"ab\"\n```\n\n\n#### replaceAt\nReplaces a char at given index\n\n```java\nString str = \"abcd\"\n\nString s = the(str).replaceAt(0, 'x'); // returns \"xbcd\"\nString s = the(str).replaceAt(6, 'x'); // returns \"abcd\"\n```\n\n### TheCollection\n\nGrammatically correct fluent checks if a collection is null or is not empty\n\n```java\nList\u003c?\u003e list = ...\n\nif (the(list).isNotEmpty()) { ... }\n\nSet\u003c?\u003e otherSet = null;\nif (the(otherSet).isEmpty()) { ... } // returns true\n```\n\n### TheMap\n\n```java\nMap\u003c?,?\u003e  map = ...\nPair\u003c?,?\u003e pair = ... // Apache Commons Pair\u003c\u003e or any Map.Entry\u003c\u003e\n\nif (the(map).isNotEmpty()) {\n    ...\n}\n```\n#### contains\nFluent `contains` checks to check if a map contains the particular entry. \nOr if the particular key has the particular value.\n```java\nif (the(map).contains(pair)) {\n    ...\n}\n\nif (the(map).contains(key, value)) {\n    ...\n}\n\nif (the(map).contains(entry(key, value))) {\n    ...\n}\n```\n#### Optional `get`\n`Map.get(key)` returns `null` if there is no value. TheMap allows to a map return an `Optional\u003c\u003e`.\n```java\nOptional\u003c?\u003e value = the(map).get(key)\n```\n\n### When\n\nPattern-ish matching in pure `Java 8`\n\n```java\nint value = ...\n\nString result = when(value)\n    .is(1).then(\"+\")\n    .is(0).then(\"zero\")\n    .is(-1).then(\"-\")\n    .orElse(\"?\"); \n```\n\nThe `when` returns value from the first matched predicate.\n\n```java\nint value = 42\n\nString result = when(value)\n    .is(42).then(\"first_42\") //result=first_42\n    .is(42).then(\"second_42\")\n    .orElse(\"?\"); \n```\n\n#### is\nThe `is` part accepts `Predicate` or a value which be compared as `Objects.equals`\n\n```java\nString result = when(value)\n    .is(v -\u003e v \u003e 0).then(\"+\")\n    .is(0).then(\"zero\") // Objects.equals(0, value)\n    .is(v -\u003e v \u003c 0).then(\"-\")\n    .orElse(\"?\"); \n```\n#### isNot\nThere is an opposise predicate `isNot`\n```java\nString result = when(value)\n    .isNot(42).then(\"not 42\")\n    .orElse(\"42 for sure\"); \n```\n\n#### and\n\nTo make a conjunction of few `is`-predicates, `and` can be used.\n```java\nint value = 5;\n\nString result = when(value)\n    .is(v -\u003e v \u003e 0).and(v-\u003e v \u003c 3).then(\"(0..3)\")\n    .is(v -\u003e v \u003e 3).and(v-\u003e v \u003c 7).then(\"(3..7)\")\n    .orElse(\"?\");\n```\n#### or\n\nTo make a disjunction of few `is`-predicates, `or` can be used.\n```java\nint value = 5;\n\nString result = when(value)\n    .is(0).or(2).or(4).then(\"0 or 2 or 4\")\n    .is(1).or(3).or(5).then(\"1 or 3 or 5\")\n    .orElse(\"?\");\n```\n\n`or` and `and` can be used together\n\n```java\nint value = 5;\n\nString result = when(value)\n    .is(1).or(2).then(\"\u003c 3\")\n    .is(v -\u003e v \u003e 6).and(v -\u003e v \u003c 10).or(5).then(\"(6;10) or 5\")\n    .is(v -\u003e v \u003e 0).and(v -\u003e v \u003c 5)\n        .or(v -\u003e v \u003e 5).and(v -\u003e v \u003c 10).then(\"(0;5) or (5;10)\")\n    .orElse(\"?\");\n```\n\n#### then\n`then` part accepts a value, `Supplier` or `Function`.\nThe function accepts the initial value.\n\n```java\nint value = ...\n\nString result = when(value)\n    .is(1).then(\"+\")\n    .is(0).then(() -\u003e \"zero\")\n    .is(v -\u003e v \u003c 0).then(val -\u003e String.valueOf(Math.abs(val))) // string of abs(value)\n    .orElse(\"?\"); \n```\n\nIt is also possible to throw an exception from `then` part\n\n```java\nint value = ...\n\nString result = when(value)\n    .is(1).then(\"+\")\n    .is(0).then(() -\u003e {\n        throw new RuntimeException();\n    })\n    .orElse(\"?\"); \n```\n\n#### orElse\n`orElse` accepts the same parameters as [then](#then)\n```java\nString result = when(value)\n    .is(1).then(\"1\")\n    .orElse(\"not 1\");\n```\n\n```java\nString result = when(value)\n    .is(1).then(\"1\")\n    .orElse(this::method); // method will be called only if value is not 1\n```\n\n```java\nString result = when(value)\n    .is(1).then(\"1\")\n    .orElse(val -\u003e String.valueOf(Math.abs(val))); \n```\n\n#### orElseThrow\nBy default `orElseThrow` throws `IllegalStateException` with default message.\n`orElseThrow` accepts a `String` to set an exception message, or `Supplier` to throw a custom one.\n\n```java\nString result = when(value)\n    .is(1).then(\"1\")\n    .orElseThrow(); // IllegalStateException with default message\n```\n\n```java\nString result = when(value)\n    .is(1).then(\"1\")\n    .orElseThrow(\"Some valuable message\");\n```\n\n```java\nString result = when(value)\n    .is(1).then(\"1\")\n    .orElseThrow(RuntimeException::new); \n```\n\n#### asOptional\n\nIf the absence of the result is normal flow. `Optional\u003c\u003e` can be used as a return value.\n\n```java\nint value = 1;\n\nOptional\u003cString\u003e result = when(value)\n    .is(0).then(\"0\")\n    .is(1).then(\"1\")\n    .asOptional(); // Optional.of(\"1\")\n\nOptional\u003cString\u003e result = when(value)\n    .is(0).then(\"0\")\n    .is(2).then(\"2\")\n    .asOptional(); // Optional.empty()\n```\n\n\n#### Complex example\n```java\nString result = when(value)\n    .is(i -\u003e i \u003c 0).then(i -\u003e String.format(\"negative %s\", -i))\n    .is(0).then(\"zero\")\n    .is(1).then(() -\u003e String.format(\"positive %s\", value))\n    .is(100_500).then(() -\u003e {\n            throw new RuntimeException();\n    })\n    .isNot(42).then(\"not 42\")\n    .orElseThrow(\"Custom exception message\");\n```\n\n### When2\n\nIt's possible to make matching with two variables\n```java\n\nint x = 1;\nint y = -2;\n\nString result = when(x, y)\n    .is(0, 0).then(\"zero\")\n    .is(p -\u003e p \u003e 0, p -\u003e p \u003e 0).then(\"I Quadrant\")\n    .is(p -\u003e p \u003c 0, p -\u003e p \u003e 0).then(\"II Quadrant\")\n    .is(p -\u003e p \u003c 0, p -\u003e p \u003c 0).then(\"III Quadrant\")\n    .is(p -\u003e p \u003e 0, p -\u003e p \u003c 0).then(\"IV Quadrant\")\n    .orElse(\"??\");\n```\n\n`and` is also supported\n\n```java\nint x = 1, y = 1;\nString result = when(x, y)\n    .is((v1, v2) -\u003e v1 + v2 \u003c 0).and((v1, v2) -\u003e v1 + v2 \u003e -10).then(\"x+y=(-10..0)\")\n    .is((v1, v2) -\u003e v1 + v2 \u003e -0).and((v1, v2) -\u003e v1 + v2 \u003c 10).then(\"x+y=(0..10)\")\n    .is((v1, v2) -\u003e v1 + v2 \u003e 10).and((v1, v2) -\u003e v1 + v2 \u003c 20).then(\"x+y=(10..20)\")\n    .orElseThrow();\n```\n\n`or` and `and` can be used together\n\n```java\n\nString result = when(x, y)\n    .is(2, 2).or(3, 3).or(4, 4).then(\"2-3-4\")\n    .isNot(1, 1).and(p -\u003e p \u003e 0, p -\u003e p \u003e 0).then(\"not 1, \u003e 0\")\n    .is(1, 2).or(2, 1).or(1, 1).then(\"1 or 2\")\n    .orElseThrow();\n```\n\n## License\n\nThis project is licensed under [Apache License, version 2.0](https://www.apache.org/licenses/LICENSE-2.0)\n\n## Installation\n\nReleases are available in [Maven Central](https://repo1.maven.org/maven2/me/dehasi/zeliba/)\n\n### Maven\n\nAdd this snippet to the pom.xml `dependencies` section:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eme.dehasi\u003c/groupId\u003e\n    \u003cartifactId\u003ezeliba\u003c/artifactId\u003e\n    \u003cversion\u003e2021.06.22\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Gradle \n\nAdd this snippet to the build.gradle `dependencies` section:\n\n```groovy\nimplementation 'me.dehasi:zeliba:2021.06.22'\n```\n\n## Contribution\nFeel free to share your ideas via issues and pull-requests.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdehasi%2Fzeliba","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdehasi%2Fzeliba","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdehasi%2Fzeliba/lists"}