From e37e9b65c3579223208e9c6ddbf5a0bd000994aa Mon Sep 17 00:00:00 2001 From: just Date: Fri, 10 Jul 2026 22:16:20 +0400 Subject: [PATCH] documentation update --- Core/Base32.cs | 22 +++++++++ Core/Base64Url.cs | 12 +++++ Core/Collections/DataMap.cs | 5 ++ Core/Collections/IDataMap.cs | 2 + Core/Collections/IMap.cs | 2 + Core/Collections/Map.cs | 5 ++ Core/Collections/MapPoint.cs | 2 + Core/Core.csproj | 2 + README.md | 96 +++++++++++++++++++++++++++++++----- 9 files changed, 137 insertions(+), 11 deletions(-) diff --git a/Core/Base32.cs b/Core/Base32.cs index 9b3514a..0f764c2 100644 --- a/Core/Base32.cs +++ b/Core/Base32.cs @@ -1,20 +1,42 @@ namespace Just.Core; +/// +/// Encoding options for . +/// +[Flags] public enum Base32EncodeOptions { + /// Standard RFC 4648 encoding (uppercase with padding). None = 0x00, + /// Use lowercase alphabet. LowerCase = 0x01, + /// Omit padding characters. NoPadding = 0x02, + /// Lowercase alphabet without padding (combines | ). LowerCaseNoPadding = 0x03, } +/// +/// RFC 4648 Base32 encoder/decoder with span-based APIs. +/// Uses stack allocation for inputs up to bytes; heap allocation otherwise. +/// public static class Base32 { + /// RFC 4648 Base32 alphabet (uppercase A-Z, 2-7). public const string Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; + /// Lowercase variant of the RFC 4648 alphabet. public const string AlphabetLower = "abcdefghijklmnopqrstuvwxyz234567"; + /// Padding character (=). public const char Padding = '='; + /// Maximum input byte count that uses stack allocation instead of heap. public const int MaxBytesStack = 250; + /// + /// Encodes a byte span into a Base32 string. + /// + /// The bytes to encode. + /// Encoding options (casing, padding). Defaults to standard RFC 4648. + /// The Base32-encoded string. [Pure] public static string Encode(ReadOnlySpan input, Base32EncodeOptions options = Base32EncodeOptions.None) { diff --git a/Core/Base64Url.cs b/Core/Base64Url.cs index f732d15..372d667 100644 --- a/Core/Base64Url.cs +++ b/Core/Base64Url.cs @@ -2,10 +2,15 @@ using System.Runtime.InteropServices; namespace Just.Core; +/// +/// URL-safe Base64 encoder/decoder for bytes, , and . +/// Uses the standard Base64Url character set (- and _ instead of + and /), padding stripped by default. +/// public static class Base64Url { private const char Padding = '='; + /// Decodes an 11-character Base64Url string into a . [Pure] public static long DecodeLong(ReadOnlySpan value) { ArgumentOutOfRangeException.ThrowIfNotEqual(value.Length, 11); @@ -24,6 +29,7 @@ public static class Base64Url return MemoryMarshal.Read(longBytes); } + /// Decodes a 22-character Base64Url string into a . [Pure] public static Guid DecodeGuid(ReadOnlySpan value) { ArgumentOutOfRangeException.ThrowIfNotEqual(value.Length, 22); @@ -42,6 +48,7 @@ public static class Base64Url return new Guid(guidBytes); } + /// Decodes a Base64Url string into a byte array. [Pure] public static byte[] Decode(ReadOnlySpan input) { if (input.IsEmpty) return []; @@ -53,6 +60,7 @@ public static class Base64Url return output[..size].ToArray(); } + /// Decodes a Base64Url string into a pre-allocated byte span. Returns the number of bytes written. [Pure] public static int Decode(ReadOnlySpan value, Span output) { var padding = (4 - (value.Length & 3)) & 3; @@ -72,6 +80,7 @@ public static class Base64Url return outputBytes; } + /// Encodes a into an 11-character Base64Url string. [Pure] public static string Encode(in long id) { Span longBytes = stackalloc byte[8]; @@ -84,6 +93,7 @@ public static class Base64Url return new string(chars[..^1]); } + /// Encodes a into a 22-character Base64Url string. [Pure] public static string Encode(in Guid id) { Span guidBytes = stackalloc byte[16]; @@ -96,6 +106,7 @@ public static class Base64Url return new string(chars[..^2]); } + /// Encodes a byte span into a Base64Url string. [Pure] public static string Encode(ReadOnlySpan input) { if (input.IsEmpty) return string.Empty; @@ -107,6 +118,7 @@ public static class Base64Url return new string(output[..strlen]); } + /// Encodes a byte span into a pre-allocated char span. Returns the number of characters written. [Pure] public static int Encode(ReadOnlySpan input, Span output) { if (input.IsEmpty) return 0; diff --git a/Core/Collections/DataMap.cs b/Core/Collections/DataMap.cs index a590f7e..c66f8f6 100644 --- a/Core/Collections/DataMap.cs +++ b/Core/Collections/DataMap.cs @@ -3,6 +3,11 @@ using System.Runtime.InteropServices; namespace Just.Core.Collections; +/// +/// A 2D grid with lazy min/max caching, cloning, and binary stream serialization. +/// Requires to support comparison and equality operators. +/// +/// The element type; must implement IComparisonOperators<T, T, bool> and IEqualityOperators<T, T, bool>. public class DataMap : Map, IDataMap, ICloneable where T : IComparisonOperators, IEqualityOperators { diff --git a/Core/Collections/IDataMap.cs b/Core/Collections/IDataMap.cs index 0054c14..b30d1e7 100644 --- a/Core/Collections/IDataMap.cs +++ b/Core/Collections/IDataMap.cs @@ -2,6 +2,8 @@ using System.Numerics; namespace Just.Core.Collections; +/// Read-only interface for a 2D grid with min/max tracking and cloning. +/// The element type; must support comparison and equality operators. public interface IDataMap : IMap, ICloneable where T : IComparisonOperators, IEqualityOperators { diff --git a/Core/Collections/IMap.cs b/Core/Collections/IMap.cs index e4ea7ba..7895ece 100644 --- a/Core/Collections/IMap.cs +++ b/Core/Collections/IMap.cs @@ -1,5 +1,7 @@ namespace Just.Core.Collections; +/// Read-only interface for a 2D grid with coordinate-based access and enumeration. +/// The type of elements in the map. public interface IMap : IReadOnlyCollection> { int Width { get; } diff --git a/Core/Collections/Map.cs b/Core/Collections/Map.cs index fddb368..fba5223 100644 --- a/Core/Collections/Map.cs +++ b/Core/Collections/Map.cs @@ -2,6 +2,11 @@ using System.Collections; namespace Just.Core.Collections; +/// +/// A 2D grid container providing indexer access, enumeration as values, +/// and conversion to a 2D array. Coordinates are clamped to valid ranges. +/// +/// The type of elements in the map. public class Map : IMap { internal readonly T[] _values; diff --git a/Core/Collections/MapPoint.cs b/Core/Collections/MapPoint.cs index bce1e93..ec3646b 100644 --- a/Core/Collections/MapPoint.cs +++ b/Core/Collections/MapPoint.cs @@ -1,5 +1,7 @@ namespace Just.Core.Collections; +/// A value and its coordinates within a . +/// The type of the map element. public readonly struct MapPoint(T value, int x, int y, IMap map) { public readonly T Value = value; diff --git a/Core/Core.csproj b/Core/Core.csproj index 6c689ef..2bb56da 100644 --- a/Core/Core.csproj +++ b/Core/Core.csproj @@ -6,6 +6,8 @@ enable Just.Core Just.Core + true + $(NoWarn);CS1591 Small .Net library with useful helper classes, functions and extensions. extensions;helpers;helper-functions diff --git a/README.md b/README.md index a6d30af..241e983 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,92 @@ -# .Net library with helpers, functions and extensions +# Just.Core -Just some stuff that is used in different projects... +Small .NET library with useful helper classes, functions, and extensions — stuff used across multiple projects. + +[![NuGet](https://img.shields.io/nuget/v/Just.Core)](https://www.nuget.org/packages/Just.Core) + +## Install + +```sh +dotnet add package Just.Core +``` ## Features -- ```Map``` and ```DataMap``` collection types -- Extensions for ```System.String``` and ```System.IO.Stream``` -- Small converters for **Base32** and **Base64Url** encodings - -## Getting Started +### Encoding -### Install from NuGet.org +**Base32** — RFC 4648 encoder/decoder with lowercase and no-padding options. -```sh -# install the package using NuGet -dotnet add package Just.Core +```csharp +var encoded = Base32.Encode(bytes); // "ABCDEFGH..." +var encoded = Base32.Encode(bytes, Base32EncodeOptions.LowerCaseNoPadding); +var bytes = Base32.Decode("ABCDEFGH..."); ``` + +**Base64Url** — URL-safe Base64 for bytes, `long`, and `Guid`. + +```csharp +var str = Base64Url.Encode(myGuid); // "5QrdUxDUVkCAEGw8pvLsEw" +var guid = Base64Url.DecodeGuid(str); +var str = Base64Url.Encode(123456789L); // "7NcVAAAAAA" +var val = Base64Url.DecodeLong(str); +``` + +### IDs + +**SeqId** — Time-based 64-bit sequential ID with configurable entropy. Thread-safe. + +```csharp +var id = SeqId.NextId(); // default instance, Strong entropy +var id = SeqId.NextId(RngEntropy.Weak); // faster, less collision-resistant + +// Custom epoch +var generator = new SeqId(new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc)); +var id = generator.Next(); +``` + +Structure: `[1 bit reserved][41 bits ms since epoch][8 bits sequence][14 bits random]` + +**GuidV8** — Time-sortable UUID v8 with extractable timestamp. + +```csharp +var guid = GuidV8.NewGuid(); // current UTC, Strong entropy +var guid = GuidV8.NewGuid(specificTime); +var when = GuidV8.ExtractTimestamp(guid); // recover timestamp (100µs precision) +``` + +### Collections + +**Map<T> / DataMap<T>** — 2D grid container with indexing, enumeration, and min/max. + +```csharp +var map = new Map(width: 10, height: 10, values); +var value = map[3, 5]; // integer or double coordinates +var point = map.Get(3.5, 5.2); // MapPoint with position metadata + +var dmap = new DataMap(values, 10, 10); +var min = dmap.Min; // MapPoint — cached +var max = dmap.Max; // lazy, thread-safe on first access + +// Stream serialization (sync + async) +dmap.WriteToStream(stream); +var copy = DataMap.ReadFromStream(stream); +``` + +**ImmutableSequence<T>** — Immutable list with structural value equality. + +```csharp +var seq = new ImmutableSequence([1, 2, 3]); +var seq2 = seq.Add(4); // new instance, seq unchanged +seq == seq2; // false — 3 vs 4 elements +new ImmutableSequence([1, 2, 3]) == seq; // true — value equality +``` + +## Supported Targets + +- .NET 8.0 (LTS) +- .NET 9.0 +- .NET 10.0 + +## License + +MIT — see [LICENSE](LICENSE).