Skip to content

Commit

Permalink
Added documentation for OpenSourced extensions (#239)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennethmugo committed Apr 16, 2024
1 parent 0cbb850 commit ea099a3
Showing 1 changed file with 97 additions and 14 deletions.
111 changes: 97 additions & 14 deletions src/Tingle.Extensions.Primitives/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ This library contains extra primitive types. These are additional to what the fr

For some primitive types, there are also some validation attributes for easier validation of input data.

## `ByteSize`
## Extra Primitive Types

### `ByteSize`

Handling of byte calculations. Extended from [`ByteSize`](https://github.com/omar/ByteSize).

Expand All @@ -13,7 +15,7 @@ var bs = ByteSize.FromKiloBytes(1.5);
Console.WriteLine(bs);
```

## `ConnectionStringBuilder`
### `ConnectionStringBuilder`

Helps you with the manipulation of connection strings. In most SDKs provided by Microsoft the builders are usually internal and cannot be reused or are very usage centric. This type helps in the manipulation of connection strings either from the final string or parts and can then produce the final string or segments.

Expand All @@ -25,7 +27,7 @@ Console.WriteLine("https", csb.GetScheme());
Console.WriteLine("abcd", csb.GetKey());
```

## `Country`
### `Country`

Easier handling of countries with support for validation.

Expand All @@ -46,7 +48,7 @@ class TestModel1
}
```

## `Currency`
### `Currency`

Easier handling of currencies with support for validation.

Expand All @@ -67,7 +69,7 @@ class TestModel1
}
```

## `Duration`
### `Duration`

`TimeSpan` is great but when dealing with values outside the .NET ecosystem you can either specify the time in seconds, milliseconds, or minutes.
This type provides an alternative, by using [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) durations e.g. `PT10M` for 10 minutes.
Expand All @@ -82,7 +84,7 @@ DateTime dt = new(2022, 08, 31, 12, 19, 10);
var equal = dt.AddMonths(1) == dt + Duration.FromMonths(1);
```

## `Etag`
### `Etag`

A convenience type for handling Etag values. For example, you can use this to read values from SQLServer's `RowVersion` or you can create your own version when working with MongoDB.
It is also useful when combining multiple values such when you want a new Etag if an entry in an array of items changes.
Expand All @@ -94,7 +96,7 @@ Console.WriteLine(etag.ToString("B")); // Fc1bBwAAAAA=
Console.WriteLine(etag); // Fc1bBwAAAAA=
```

## `ImageDimensions`
### `ImageDimensions`

Simple convenience for storing image dimensions similar to `System.Drawing.Size`.

Expand All @@ -103,7 +105,7 @@ var value = new ImageDimensions(50, 45);
Console.WriteLine(value); // 50px by 45px
```

## `ImageDimensionsRange`
### `ImageDimensionsRange`

A type that eases the check for whether an image's dimensions are contained in a given range.

Expand All @@ -118,7 +120,7 @@ var dimensions = new ImageDimensions(width, height);
Console.WriteLine(range.IsWithin(dimensions)); // true
```

## `Ksuid`
### `Ksuid`

A K-Sortable Globally Unique Identifier, based on the reference implementation from [Segment](https://github.com/segmentio/ksuid).

Expand All @@ -131,7 +133,7 @@ if (Ksuid.TryParse("0o5Fs0EELR0fUjHjbCnEtdUwQe3", out var id)) {
}
```

## `Language`
### `Language`

Easier handling of languages with support for validation.

Expand All @@ -152,7 +154,7 @@ class TestModel1
}
```

## `SequenceNumber`
### `SequenceNumber`

A sequential number inspired by Twitter's (late) Snowflake project and Instagram's implementation.
This is very useful for situations where you want non-predictable identifiers.
Expand All @@ -163,7 +165,7 @@ var sequenceNumber1 = SequenceNumber.Generate(); // generation
Console.WriteLine(sequenceNumber1);
```

## `SwiftCode`
### `SwiftCode`

Represents a SWIFT Code broken down into its components. The format of a Swift Code is as specified under ISO-9362.

Expand All @@ -175,7 +177,7 @@ Console.WriteLine(sw.Location); // "NX"
Console.WriteLine(sw.Branch); // "XXX"
```

## `Keygen`
### `Keygen`

Helper for generating non-sequential keys such as those use as client secrets, webhook secrets, signing keys, etc.
The keys can be generated from bytes, strings, and numbers where deterministic outputs are desired.
Expand All @@ -190,7 +192,7 @@ Console.WriteLine(Keygen.Create("000", Keygen.OutputFormat.Hex, Encoding.ASCII))
Console.WriteLine(Keygen.Create("000", Keygen.OutputFormat.Hex, Encoding.Unicode)); // MAAwADAA
```

## Conversion
### Conversion

Most of the types have conversion to/from JSON using `System.Text.Json`.
Support for Type converters is also included to allow binding via `IConfiguration` instances.
Expand All @@ -210,3 +212,84 @@ Support for Type converters is also included to allow binding via `IConfiguratio
|`SequenceNumber`|☑|☑|
|`SwiftCode`|☑|☑|
|`Keygen`|☐|☐|

There are also some convenience extension methods on framework types that can be useful for various tasks. They are explained below:

## Extensions for shortening numbers

You may want to convert the numeric values to its equivalent string representation. The output will be an abbreviated string. For example, you may want to represent `1,000,000` as `1M` or `1,000` as `1K`. This can be done as shown below:

```cs
long number = 1_000;
var converted = number.ToStringAbbreviated();
Console.WriteLine(converted); // 1K
```

You can use overloads for `ToStringAbbreviated(...)` to supply an `IFormatProvider` if you need to abbreviate a number using culture-specific formatting information.

## Extensions for string protection

Sometimes you may want to mask certain portions of strings that may contain sensitive information. An example is a password or an authentication key to access an API. An example of how you can do this is shown below:

```cs
var key = "EcsmGa/wXv/HlA==";
var result = key.Protect();
Console.WriteLine(result); // Ecs*************
```

By default, only the first 20% of the string will be kept as is. The remaining characters will be replaced with asterisks (*). To alter this default behavior you can supply different values to the following parameters:

- `toKeep`: Specifies how many of the characters in the string aren't replaced with the replacement character (which is an asterisk by default) as a percentage.
- `position`: The position of the string to protect. By default, the `StringProtectionPosition` is `End`. You can alter this to `Middle` or `Start`.
- `replacementChar`: The character to replace the protected string characters with. By default, it is an asterisk (*).
- `replacementLength`: The length of the replacement string using the replacement characters.

## Extensions for splitting a string in Pascal casing into multiple words

[Pascal case](https://www.pluralsight.com/blog/software-development/programming-naming-conventions-explained#pascal-case).

```cs
var str = "HomeAndAway";
var result = str.PascalSplit();
Console.WriteLine(result); // Home And Away
```

By default, the string will be split, and a single whitespace will be inserted in between the words. If you'd like to change the separator that is inserted between the words you can set the `separator` parameter in `PascalSplit(...)`.

## Extensions to the get the value declared on the Enum using EnumMemberAttribute

For example:

```cs
public enum Platform
{
[EnumMember(Value = "ios")]
iOS,

Android
}
```

In the declared enumerations to represent the iOS and Android platforms. Note that only the iOS member has an `EnumMemberAttribute` annotated on it.

```cs
var platform = Platform.iOS;
var result = tt.GetEnumMemberAttrValue();
Console.WriteLine(result); // ios
platform = Platform.Android;
result = tt.GetEnumMemberAttrValue();
// result is null here
```

Since the `iOS` member is annotated with an `EnumMemberAttribute`, `ios` is returned as expected. However, the `Android` member doesn't have that annotation and thus the value that will be returned will be `null`. If you'd like to return the default value in lower case format when there are members without an `EnumMemberAttribute` annotation:

```cs
var platform = Platform.iOS;
var result = tt.GetEnumMemberAttrValueOrDefault();
Console.WriteLine(result); // ios
platform = Platform.Android;
result = tt.GetEnumMemberAttrValueOrDefault();
Console.WriteLine(result); // android
```

0 comments on commit ea099a3

Please sign in to comment.