{"id":51010137,"url":"https://github.com/marcos-venicius/quang-csharp","last_synced_at":"2026-06-21T01:33:32.547Z","repository":{"id":349033717,"uuid":"1200830386","full_name":"marcos-venicius/quang-csharp","owner":"marcos-venicius","description":"`Quang` is meant to be a \"query\" language for your tools.","archived":false,"fork":false,"pushed_at":"2026-05-15T14:34:15.000Z","size":33,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-21T01:33:30.663Z","etag":null,"topics":["cli","csharp","library","quang","query-language"],"latest_commit_sha":null,"homepage":"https://www.nuget.org/packages/Quang","language":"C#","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/marcos-venicius.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":"2026-04-03T21:57:32.000Z","updated_at":"2026-05-15T14:37:45.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/marcos-venicius/quang-csharp","commit_stats":null,"previous_names":["marcos-venicius/quang-csharp"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/marcos-venicius/quang-csharp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcos-venicius%2Fquang-csharp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcos-venicius%2Fquang-csharp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcos-venicius%2Fquang-csharp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcos-venicius%2Fquang-csharp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marcos-venicius","download_url":"https://codeload.github.com/marcos-venicius/quang-csharp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcos-venicius%2Fquang-csharp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34591166,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-20T02:00:06.407Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["cli","csharp","library","quang","query-language"],"created_at":"2026-06-21T01:33:31.373Z","updated_at":"2026-06-21T01:33:32.535Z","avatar_url":"https://github.com/marcos-venicius.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Quang\n\n`Quang` is meant to be a \"query\" language for your tools.\n\n`Quang` extends for `Query Language`.\n\nYou can use the language to implement filters in your applications without the need of tons of flags to your user,\njust provide a simple and consise integrated language and let the user build the filter himself.\n\nSo, it is at the end a _\"language as a lib\"_.\n\n_There is a full [playlist on youtube](https://youtube.com/playlist?list=PL3YefAkg_zCgPTINetXJ7Aatpps2DECcW\u0026si=_jBBPe7s6Ne4B70s) creating this project._\n\n## Api and language details\n\nDoes not matter what kind of query you provide as input to the evaluator, it will always return `true` or `false`. If the query is empty, it will always return `true`.\n\n**Data Types**\n\n| name     | supported | format        | description                                                                   |\n| -------- | --------- | ------------- | ----------------------------------------------------------------------------- |\n| Integers | yes       | `[0-9]+`      | golang 64bit signed integers                                                  |\n| Atoms    | yes       | `:[a-zA-Z_]+` | it works like enumerators                                                     |\n| String   | yes       | `'.*'`        | you can scape string with `\\'`                                                |\n| Boolean  | yes       | `true\\|false` |                                                                               |\n| Nil      | yes       | `nil`         | represents all kinds of empty values (\"\", nil) (zero is not considered empty) |\n| Floats   | yes       | `\\d+\\.\\d*`    | golang 64bit floats                                                           |\n\n**Keywords**\n\n| name     | description   | usage            |\n| -------- | ------------- | ---------------- |\n| not      | negation      | `not false`      |\n| and      | logical and   | `true and true`  |\n| or       | logical or    | `true or false`  |\n| nil      | null value    | `name eq nil`    |\n| true     | boolean true  | `alive eq true`  |\n| false    | boolean false | `alive eq false` |\n\n**Operators**\n\n| name     | description                                                                                        | example                 |\n| -------- | -------------------------------------------------------------------------------------------------- | ----------------------- |\n| not      | negate boolean expressions                                                                         | `not (status eq 400)`   |\n| eq       | check if `a` is equal to `b`. strict types. (Integers, Strings, Booleans, Nils, Floats, Atoms)     | `a eq b`                |\n| ne       | check if `a` is not equal to `b`. strict types. (Integers, Strings, Booleans, Nils, Floats, Atoms) | `a ne b`                |\n| lt       | check if `a` is less than `b`. strict types. (Integers, Strings)                                   | `a lt b`                |\n| gt       | check if `a` is greater than `b`. strict types. (Integers, Strings)                                | `a gt b`                |\n| lte      | check if `a` is less than or equal to `b`. strict types. (Integers, Strings)                       | `a lte b`               |\n| gte      | check if `a` is greater than or equal to `b`. strict types. (Integers, Strings)                    | `a gte b`               |\n| reg      | check if `a` matches pattern `b`. `b` accepts valid regex. `a` should be a string                  | `a reg b`               |\n\n**Basic syntax**\n\nPretend we have a list of computers that have the following properties:\n\n- Identifier\n- Running\n- Cors\n\nSo, we could query something like:\n\n```elixir\n(running eq true and cors gte 4 and cors lte 10) or (running eq false and identifier reg 'ML-\\d+') or identifier eq nil\n```\n\n\u003e [!TIP]\n\u003e This repository is a port of [Quang](https://github.com/marcos-venicius/quang) for CSharp. See the original repository for more information.\n\n# How to Use\n\nLet's pretend you have a list of people and you need to build a CLI to search this list.\n\n```\nusername,age,sex,weight\nuser001,25,M,70.2\nuser002,31,F,60.7\nuser003,22,M,68.4\nuser004,29,F,55.9\nuser005,35,M,80.1\nuser006,28,F,62.5\nuser007,24,M,72.3\nuser008,30,F,59.6\nuser009,27,M,75.8\nuser010,33,F,65.2\nuser011,26,M,71.4\nuser012,32,F,63.7\nuser013,23,M,69.9\nuser014,34,F,58.3\n```\n\nThen, you can with a **less than 20 lines of code** integrate the language with your cli.\n\nHere is a **fully function example**:\n\n```csharp\nusing Quang;\n\nif (args.Length != 1)\n{\n    Console.WriteLine(\"Usage: dotnet run -- \u003csearch-query\u003e\");\n\n    return;\n}\n\nstring[][] content = [.. File.ReadAllLines(\"./logs.txt\")[1..].Select(line =\u003e line.Split(','))];\n\nvar quang = new Quang.Quang(args[0])\n    .Init()\n    .SyntaxExpectAtom(\":f\")\n    .SyntaxExpectAtom(\":m\")\n    .SyntaxExpectSymbol(\"age\", new ExpressionValueTypeInfo\u003cIntegerExpression\u003e())\n    .SyntaxExpectSymbol(\"weight\", new ExpressionValueTypeInfo\u003cFloatExpression\u003e())\n    .SyntaxExpectSymbol(\"username\", new ExpressionValueTypeInfo\u003cStringExpression\u003e())\n    .SyntaxExpectSymbol(\"sex\", new ExpressionValueTypeInfo\u003cAtomExpression\u003e());\n\nforeach (var line in content)\n{\n    var username = line[0].Trim();\n    var age = int.Parse(line[1]);\n    var sex = line[2].ToLower().Trim();\n    var weight = float.Parse(line[3]);\n\n    var evaluator = quang.Evaluator()\n        .AddStringVar(\"username\", username)\n        .AddAtomVar(\"sex\", $\":{sex}\")\n        .AddIntegerVar(\"age\", age)\n        .AddFloatVar(\"weight\", weight);\n\n    if (evaluator.Evaluate())\n        Console.WriteLine($\"Matched: {username},{age},{sex},{weight}\");\n}\n```\n\nIn fact, this example is present [here](./LogSearch/Program.cs).\n\nThen, if you run and use this filter: `dotnet run -- 'sex eq :m and weight lte 70.0 and age gte 23'`, it should return you this:\n\n```\nMatched: user013,23,m,69.9\n```\n\n**✨ Is that easy!**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcos-venicius%2Fquang-csharp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcos-venicius%2Fquang-csharp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcos-venicius%2Fquang-csharp/lists"}