{"id":30673769,"url":"https://github.com/starcruisestudios/phxlib","last_synced_at":"2026-03-16T20:38:20.063Z","repository":{"id":144661026,"uuid":"521848049","full_name":"StarCruiseStudios/PhxLib","owner":"StarCruiseStudios","description":"Core C# language and development extensions","archived":false,"fork":false,"pushed_at":"2025-06-28T09:47:08.000Z","size":833,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-28T10:03:30.977Z","etag":null,"topics":["csharp"],"latest_commit_sha":null,"homepage":"","language":"C#","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/StarCruiseStudios.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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":"2022-08-06T04:41:46.000Z","updated_at":"2025-06-28T09:47:12.000Z","dependencies_parsed_at":"2024-05-05T06:24:01.522Z","dependency_job_id":"671a93f3-f7a0-42d4-b11e-6af020d838f3","html_url":"https://github.com/StarCruiseStudios/PhxLib","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/StarCruiseStudios/PhxLib","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StarCruiseStudios%2FPhxLib","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StarCruiseStudios%2FPhxLib/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StarCruiseStudios%2FPhxLib/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StarCruiseStudios%2FPhxLib/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/StarCruiseStudios","download_url":"https://codeload.github.com/StarCruiseStudios/PhxLib/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StarCruiseStudios%2FPhxLib/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273081103,"owners_count":25042275,"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","status":"online","status_checked_at":"2025-09-01T02:00:09.058Z","response_time":120,"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":["csharp"],"created_at":"2025-09-01T06:04:31.254Z","updated_at":"2026-03-16T20:38:20.015Z","avatar_url":"https://github.com/StarCruiseStudios.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PhxLib\nPHX Lib core utilities and extensions.\n\n## PHX.Collections\nNew collection types that have more convenient interfaces and covariant generics.\n\n### Interfaces\n* `IPhxContainer` - A collection that contains multiple elements.\n* `IPhxCollection`/`IPhxMutableCollection` - A collection of elements that can be queried.\n* `IPhxList`/`IPhxMutableList` - A collection whose elements are ordered.\n* `IPhxCatalog` - A collection whose elements are unique.\n* `IPhxSet`/`IPhxMutableSet` - A collection whose elements are unique and can be merged or compared to other collections.\n* `IPhxMap`/`IPhxMutableMap` - A collection of key value pairs.\n* `IPhxMultiMap`/`IPhxMutableMultiMap` - A collection of mappings from keys to one or more values.\n* `IPhxKeyValuePair` - A single key value pair.\n\n### Collection Types\n* ImmutablePhxList\n* ImmutablePhxSet\n* ImmutablePhxMap\n* PhxArrayList\n* PhxHashSet\n* PhxHashMap\n* PhxArrayListMultiMap\n* PhxKeyValuePair\n\n### Conversion and Creation Helpers\n* IEnumerableConversionExtensions - Methods for converting an existing IEnumerable to a Phx.Collections type.\n* IEnumerableCopyExtensions - Methods for copying an existing IEnumerable into a new Phx.Collections type.\n* PhxCollections - Methods for creating new Phx.Collections types.\n\n## PHX.Debug\nUtilities that assist in the debugging of code.\n\n### IDebugDisplay\nProvides an interface for a different string representation of an object intended for debugging rather than user display.\n```csharp\nusing System.Diagnostics;\nusing Phx.Debug;\n\n// System.Diagnostics.DebuggerDisplay attribute controls what is displayed in\n// the IDEs debugger view.\n[DebuggerDisplay(DebugDisplay.DEBUGGER_DISPLAY_STRING)]\npublic class MyClass : IDebugDisplay {\n    // ToDebugDisplay() method is also available to invoke in debug logging.\n    public string ToDebugDisplay() {\n        return \"MyClass\";\n    }\n    \n    public override string ToString() {\n        // Or provide a default implementation that is intended for user display.\n        return ToDebugDisplay();\n    }\n}\n```\n\n## PHX.Dev\nUtilities that assist in development tasks and documentation.\n\n### ToDo\nFunctions that throws a `NotImplementedException` or `InvalidOperationException`\nwith that describe the reason the code path is invalid. This is similar to throwing the\n`NotImplementedException` or `InvalidOperationException` directly, except it \n\"returns\" a value to work better with assignment statements and argument passing.\n```csharp\nusing Phx.Dev;\n                \nvar myList = new List\u003cstring\u003e {\n    ToDo.NotImplementedYet\u003cstring\u003e(\"This parameter need to be computed.\")\n};\n\nint i = Random.Shared.Next();\nswitch (i) {\n    case 0:\n        ToDo.NotImplementedYet(\"This case needs to be handled.\");\n        break;\n    default:\n        ToDo.NotSupportedYet(\"We haven't figured out how to handle this yet.\");\n        break;\n}\n```\n\n### ToDo Attributes\nAttributes that document code that needs to be implemented or issues that need\nto be resolved but that do not prevent execution. These attributes are similar\nto using comments except they are more easily searched and the compiler helps\navoid typos and enforce the presence of descriptions.\n```csharp\nusing Phx.Dev;\n\n[KnownIssue(\"This class doesn't work all the time.\",\n    workaround: \"Use the NotBroken class instead.\",\n    link: \"www.todo/12345\")]\npublic class BrokenClass { } \n\npublic class TooBigClass {\n    [Refactor(\"This function does too much and can be broken up into component classes.\")]\n    public void BigFunction() { }\n}\n\n[ToDo(\"This class should optimize its database accesses.\", link: \"www.todo/67890\")]\npublic class DatabaseClass { }\n```\n\n## PHX.Lang\nUtilities that add or extend language features.\n\n### ICheckedDisposable\nExtends the `IDisposable` interface with a publicly readable boolean property\nthat indicates if the instance has been disposed.\n\n```csharp\nusing Phx.Lang;\n\npublic class MyResource: ICheckedDisposable {\n    public bool IsDisposed { get; private set; }\n\n    public void Dispose() {\n        Dispose(disposing: true);\n        GC.SuppressFinalize(this);\n    }\n    \n    protected virtual void Dispose(bool disposing) {\n        if(!IsDisposed) {\n            if(disposing) {\n                // Dispose managed resources.\n            }\n            IsDisposed = true;\n        }\n    }\n    \n    ~MyResource() {\n        Dispose(disposing: false);\n    }\n}\n```\n\n### Late.Init\nProvides a self documenting way to indicate a non-nullable value will be \ninitialized after the constructor is invoked, but before its first access.\n\nThis should only be used if it is guaranteed that the value will be set before\nit is accessed (via late injection, separate initializer methods, etc).\n\nThis is equivalent to using `null!`, but is more clear about the developer's\nintentions.\n\n```csharp\nusing Phx.Lang;\n\nstring str = Late.Init\u003cstring\u003e();\n```\n\n### Optional\nOptional can be used as a wrapper around a return value that communicates to the\ncaller that a value may not be returned. It enforces that that case is handled,\nand provides built in helper methods to handle it.\n\n```csharp\nusing Phx.Lang;\n\nprivate IOptional\u003cstring\u003e GetNickName() {\n    return Optional.OfNullable(nickName);\n}\n\nprivate void UseAnOptional() {\n    var nickName = GetNickName().OrElse(() =\u003e StringUtils.EmptyString);\n}\n```\nHelper methods include:\n```csharp\nusing Phx.Lang;\n                \n// Create an Optional from a value that may be null.\nstring? nickName = ReadNickName();\nIOptional\u003cstring\u003e optionalNickName = Optional.OfNullable(nickName);\n\n// Use Optional.Of() or Optional.EMPTY to explicitly create an optional if it is\n// not possible to use Optional.OfNullable().\nIOptional\u003cstring\u003e result;\ntry {\n    var value = ReadValue();\n    result = Optional.Of(value);\n} catch (Exception) {\n    result = Optional\u003cstring\u003e.EMPTY;\n}\n\n// Use Optional.If() to create an optional from a boolean condition.\nIOptional\u003cint\u003e optional = Optional.If(valueIsSet(), 10);\n```\n```csharp\nusing Phx.Lang;\n\n// Perform custom logic based on whether the optional is present\nif (optional.IsPresent) {\n    // Always check `IsPresent` first as `Value` will throw an exception if the \n    // optional is empty.\n    var myValue = optional.Value;\n}\n\nif (optional.IsEmpty) {\n    return;\n}\n```\n```csharp\nusing Phx.Lang;\n\n// Functional methods to handle the presence or absence of an optional value.\noptional.IfPresent(myValue =\u003e { /* ... */ });\noptional.IfEmpty(() =\u003e { /* ... */ });\n```\n```csharp\nusing Phx.Lang;\n\n// Operate on or transform an optional value only if it is present.\nIOptional\u003cstring\u003e optStr = optional.Map\u003cint, string\u003e(intValue =\u003e Optional.Of(intValue.ToString()));\n```\n```csharp\nusing Phx.Lang;\n\n// Get default values or try alternatives if an optional is not present.\nvar v = optional.OrElse(() =\u003e 100);\n\nvar v2 = optional.OrTry(() =\u003e AnotherMethodThatReturnsOptional())\n        .OrTry(() =\u003e ADifferentMethodThatReturnsOptional())\n        .OrThrow(() =\u003e new InvalidOperationException(\"None of the optional values were present.\"));\n```\n\n### Result\nThe `Result` class allows a method to return a value or indicate failure without\nthrowing exceptions. This enforces that the error cases are handled, and allows\nenumerations of the different error states.\n\n```csharp\nusing Phx.Lang;\n\nprivate IResult\u003cstring, DatabaseException\u003e ReadDatabaseEntry() {\n    return Result.Success\u003cstring, DatabaseException\u003e(\"Entry\");\n}\n\nprivate void UseAResult() {\n    var entry = ReadDatabaseEntry().OrElse(() =\u003e \"No Entry\");\n}\n```\nThe following helper methods are provided:\n```csharp\nusing Phx.Lang;\n                \n// Create a result from a successful value or exception.\nResult.Success(10);\nResult.Failure(new Exception());\n```\n```csharp\nusing Phx.Lang;\n\n// Check if the result is successful.\nvar result = GetAValue();\nif (result.IsSuccess) {\n    var value = (result as Success\u003cstring, Exception\u003e)!.Result;\n}\n\nif (result.IsFailure) {\n    var error = (result as Failure\u003cstring, Exception\u003e)!.Error;\n}\n```\n```csharp\nusing Phx.Lang;\n\n// Check the result for a specific outcome.\nif (result.Contains(it =\u003e it == \"Hello\")) { /* ... */ }\n\nif (result.ContainsError(it =\u003e it is DatabaseException)) { /* ... */ }\n```\n```csharp\nusing Phx.Lang;\n\n// Operate on or transform a result if it is successful.\nvar stringResult = result.Map(value =\u003e value.ToString());\n\n// Operate on or transform a result if it failed.\nvar newResult = result.MapError(ex =\u003e new ParseException(ex));\n```\n```csharp\nusing Phx.Lang;\n\n// Get default values or try alternatives if a result failed.\nvar valueWithAlternative = result.OrElse(() =\u003e \"Alternative\");\nvar requiredValue = result.OrThrow();\n```\n\n### Try.All\nAdditional utilities for trying multiple actions that may throw exceptions. If\nany exceptions were thrown, they are aggregated into a single \n`AggregateException` that is thrown after all actions have been executed. This\nis not an asynchronous operation, all actions are executed sequentially.\n```csharp\nusing Phx.Lang;\n\ntry {\n    Try.All(\n        () =\u003e { DoFirstThing(); },\n        () =\u003e { DoSecondThing(); },\n        () =\u003e { DoThirdThing(); }\n    );\n} catch (AggregateException ex) {\n    foreach (var exception in ex.InnerExceptions) {\n        // ...\n    }\n}\n\nIEnumerable\u003cint\u003e allElements = GetElements();\n\ntry {\n    Try.All((element) =\u003e { \n        DoSomethingWithEachItem(element); \n    }, allElements);\n} catch (AggregateException ex) {\n    ex.Handle((innerException) =\u003e {\n        log(innerException);\n        return true;\n    });\n}\n```\n\n### Unit\nUnit is type that is equivalent to the instantiation of `void`.\nIt is useful to document that a function will never return a value, or as a way\nto pass around function references whose generic parameters require a return \ntype.\n\n```csharp\nusing Phx.Lang;\nusing static Phx.Lang.Unit;\n\npublic Result\u003cUnit, Exception\u003e FunctionWithSideEffect() {\n    if (PerformSomeSideEffect()) {\n        return Result.Success(UNIT);\n    } else {\n        return Result.Failure(new Exception());\n    } \n}\n\npublic Unit AssertFail() {\n    throw new Exception(); \n}\n```\n\n### String Utils and Extensions\nVarious string utilities and extensions are also provided.\n```csharp\nusing Phx.Lang;\nusing static Phx.Lang.StringUtils;\n\n// Constant string values.\npublic void FunctionWithDefault(string str = EmptyString) {\n    // String.Empty is a readonly field and cannot be used as a default argument\n    // or parameter in Attributes. EmptyString is a constant and can be used in\n    // those cases.\n}\n\npublic string GetStringValue(string? value) {\n    return value?.ToString() ?? NullString;\n}\n```\n```csharp\nusing Phx.Lang;\n\n// Extension methods for converting objects to string.\nobject? obj = null;\nstring str = obj.ToStringSafe();\n\ntroublesomeObject.ToDebugDisplayString();\n```\n```csharp\nusing Phx.Lang;\n\n// Utilities for inline string building.\nvar newName = BuildString(sb =\u003e {\n    sb.Append(\"First\");\n    sb.Append(\"Last\");\n});\n```\n```csharp\nusing Phx.Lang;\n\n// Extension methods for manipulating and escaping strings.\nvar uppercase = \"hello\".StartUppercase();\nvar lowercase = \"Hello\".StartLowercase();\nvar implClassName = \"IMyInterface\".RemoveLeadingI();\n\nvar verbatimString = \"\\\"Hello\\\"\".EscapeVerbatimString();\nvar unescapedVerbatimString = verbatimString.UnescapeVerbatimString();\n\nvar quoteString = \"\\\"Hello\\\"\".EscapeStringQuotes();\nvar unescapedQuoteString = quoteString.UnescapeStringQuotes();\n```\n```csharp\nusing Phx.Lang;\n\n// String case conversions\nvar constantName = \"someVariableName\".FromCamelCase().ToCapsCase();\n\nif (inputValue.FromPascalCase().IsValid) {\n    // ...\n}\n\n// Conversions and validations support:\n// * camelCase\n// * CAPS_CASE\n// * kebab-case\n// * PascalCase\n// * snake_case\n```\n\n---\n\n\u003cdiv align=\"center\"\u003e\nCopyright (c) 2022 Star Cruise Studios LLC. All rights reserved.\u003cbr/\u003e\nLicensed under the Apache License, Version 2.0.\u003cbr/\u003e\nSee http://www.apache.org/licenses/LICENSE-2.0 for full license information.\u003cbr/\u003e\n\u003c/div\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstarcruisestudios%2Fphxlib","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstarcruisestudios%2Fphxlib","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstarcruisestudios%2Fphxlib/lists"}