Skip to content

Commit

Permalink
Add support for multiple parameters.
Browse files Browse the repository at this point in the history
  • Loading branch information
DearVa committed Dec 7, 2023
1 parent 65bdf24 commit 7a556c3
Show file tree
Hide file tree
Showing 15 changed files with 772 additions and 671 deletions.
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ We welcome contributions to this project! Whether it's reporting bugs, suggestin
## TODO
- [x] Nuget package.
- [x] Multiple parameters, use `T[]`.
- [ ] Automatically generate help documents.
- [ ] Check for excess parameters.
- [ ] Parameter combination, e.g. `-it` will both open `-i` and `-t`.
3 changes: 2 additions & 1 deletion readme_cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,8 @@

## 待办事项

- [ ] Nuget 包。
- [x] Nuget 包。
- [x] 解析多个参数,使用`T[]`
- [ ] 自动生成帮助文档。
- [ ] 检查多余参数。
- [ ] 参数组合,例如 `-it` 将同时开启 `-i``-t`
2 changes: 1 addition & 1 deletion src/.idea/.idea.AntelCat.Parameterization/.idea/.name

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

69 changes: 48 additions & 21 deletions src/Antelcat.Parameterization.Demo/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ public static void Main(string[] args)

[Command(ShortName = "ps", Description = "Display a list of container(s) resources usage statistics")]
private static void Stats(
[Argument(FullName = "all", ShortName = "a", Description = "Show all containers (default shows just running)", DefaultValue = "true")]
[Argument(FullName = "all", ShortName = 'a', Description = "Show all containers (default shows just running)", DefaultValue = "true")]
bool showAll = false)
{
Console.WriteLine("CONTAINER_ID IMAGE NAME STATUS");
Console.WriteLine("CONTAINER_ID IMAGE NAME STATUS PORTS");
foreach (var container in Containers.Where(container => showAll || container.IsRunning))
{
Console.WriteLine($"{container.Id} {container.Image} {container.Name} {(container.IsRunning ? "running" : "stopped")}");
Expand Down Expand Up @@ -74,11 +74,14 @@ private static void Pull(Image image)
}

[Command]
private static void Run(Image image, string? name = null)
private static void Run(
Image image,
string? name = null,
[Argument(ShortName = 'p', Converter = typeof(PortMappingConverter))] PortMapping[]? portMappings = null)
{
Pull(image);
name ??= image.Name;
var container = new Container(image, Guid.NewGuid().ToString("N")[..8], name, true);
var container = new Container(image, Guid.NewGuid().ToString("N")[..8], name, true, portMappings);
Containers.Add(container);
Console.WriteLine(container);
}
Expand All @@ -105,22 +108,7 @@ private static void Exit()
}
}

public class ImageConverter : StringConverter
{
public override object ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object? value)
{
if (value is not string str) throw new ArgumentException("Invalid image string format");
var args = str.Split(':');
return args switch
{
{ Length: 1 } => new Image(str, null),
{ Length: 2 } => new Image(args[0], Version.Parse(args[1])),
_ => throw new ArgumentException("Invalid image string format")
};
}
}

public class Container(Image image, string id, string name, bool isRunning)
public class Container(Image image, string id, string name, bool isRunning, PortMapping[]? portMappings)
{
public override int GetHashCode()
{
Expand All @@ -134,13 +122,29 @@ public virtual bool Equals(Container? other)

public override string ToString()
{
return $"{Image} {Name} {(IsRunning ? "running" : "stopped")}";
return $"{Image} {Name} {(IsRunning ? "running" : "stopped")} {(PortMappings == null ? string.Empty : string.Join<PortMapping>(", ", PortMappings))}";
}

public Image Image { get; } = image;
public string Id { get; } = id;
public string Name { get; init; } = name;
public bool IsRunning { get; set; } = isRunning;
public PortMapping[]? PortMappings { get; } = portMappings;
}

public class ImageConverter : StringConverter
{
public override object ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object? value)
{
if (value is not string str) throw new ArgumentException("Invalid image string format");
var args = str.Split(':');
return args switch
{
{ Length: 1 } => new Image(str, null),
{ Length: 2 } => new Image(args[0], Version.Parse(args[1])),
_ => throw new ArgumentException("Invalid image string format")
};
}
}

[TypeConverter(typeof(ImageConverter))]
Expand All @@ -150,4 +154,27 @@ public override string ToString()
{
return $"{Name}:{Version?.ToString() ?? "latest"}";
}
}

public class PortMappingConverter : StringConverter
{
public override object ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object? value)
{
if (value is not string str) throw new ArgumentException("Invalid port mapping string format");
var args = str.Split(':');
return args switch
{
{ Length: 1 } => new PortMapping(int.Parse(args[0]), int.Parse(args[0])),
{ Length: 2 } => new PortMapping(int.Parse(args[0]), int.Parse(args[1])),
_ => throw new ArgumentException("Invalid port mapping string format")
};
}
}

public record PortMapping(int HostPort, int ContainerPort)
{
public override string ToString()
{
return $"{HostPort}->{ContainerPort}/tcp";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class ArgumentAttribute : Attribute
/// <summary>
/// ShortName switch, e.g. -n
/// </summary>
public string? ShortName { get; set; }
public char ShortName { get; set; }

public string? Description { get; set; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,79 +10,79 @@ namespace Antelcat.Parameterization.SourceGenerators.Extensions;

public static class EnumerableExtension
{
/// <summary>
/// Python: enumerator
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="enumerable"></param>
/// <param name="startIndex"></param>
/// <param name="step"></param>
/// <returns></returns>
public static IEnumerable<(int index, T value)> WithIndex<T>(
this IEnumerable<T> enumerable,
int startIndex = 0,
int step = 1)
{
/// <summary>
/// Python: enumerator
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="enumerable"></param>
/// <param name="startIndex"></param>
/// <param name="step"></param>
/// <returns></returns>
public static IEnumerable<(int index, T value)> WithIndex<T>(
this IEnumerable<T> enumerable,
int startIndex = 0,
int step = 1)
{

foreach (var item in enumerable)
{
yield return (startIndex, item);
startIndex += step;
}
}
foreach (var item in enumerable)
{
yield return (startIndex, item);
startIndex += step;
}
}

public static IEnumerable<ValueTuple<T1, T2>> Zip<T1, T2>(
this IEnumerable<T1> source1,
IEnumerable<T2> source2)
{
return source1.Zip(source2, static (a, b) => (a, b));
}
public static IEnumerable<ValueTuple<T1, T2>> Zip<T1, T2>(
this IEnumerable<T1> source1,
IEnumerable<T2> source2)
{
return source1.Zip(source2, static (a, b) => (a, b));
}

public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> enumerable)
{
return new(enumerable);
}
public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> enumerable)
{
return new(enumerable);
}

public static IEnumerable<T> Reversed<T>(this IList<T> list)
{
for (var i = list.Count - 1; i >= 0; i--)
{
yield return list[i];
}
}
public static IEnumerable<T> Reversed<T>(this IList<T> list)
{
for (var i = list.Count - 1; i >= 0; i--)
{
yield return list[i];
}
}

public static int FindIndexOf<T>(this IList<T> list, Predicate<T> predicate)
{
for (var i = 0; i < list.Count; i++)
{
if (predicate(list[i]))
{
return i;
}
}
public static int FindIndexOf<T>(this IList<T> list, Predicate<T> predicate)
{
for (var i = 0; i < list.Count; i++)
{
if (predicate(list[i]))
{
return i;
}
}

return -1;
}
return -1;
}

/// <summary>
/// 完全枚举一个 <see cref="IEnumerable"/>,并丢弃所有元素
/// </summary>
/// <param name="enumerable"></param>
[MethodImpl(MethodImplOptions.NoOptimization)]
public static void Discard(this IEnumerable enumerable)
{
foreach (var _ in enumerable) { }
}
/// <summary>
/// 完全枚举一个 <see cref="IEnumerable"/>,并丢弃所有元素
/// </summary>
/// <param name="enumerable"></param>
[MethodImpl(MethodImplOptions.NoOptimization)]
public static void Discard(this IEnumerable enumerable)
{
foreach (var _ in enumerable) { }
}

/// <summary>
/// 完全枚举一个 <see cref="IEnumerable{T}"/>,并丢弃所有元素
/// </summary>
/// <param name="enumerable"></param>
/// <typeparam name="T"></typeparam>
[MethodImpl(MethodImplOptions.NoOptimization)]
[DebuggerNonUserCode]
public static void Discard<T>(this IEnumerable<T> enumerable)
{
foreach (var _ in enumerable) { }
}
/// <summary>
/// 完全枚举一个 <see cref="IEnumerable{T}"/>,并丢弃所有元素
/// </summary>
/// <param name="enumerable"></param>
/// <typeparam name="T"></typeparam>
[MethodImpl(MethodImplOptions.NoOptimization)]
[DebuggerNonUserCode]
public static void Discard<T>(this IEnumerable<T> enumerable)
{
foreach (var _ in enumerable) { }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,43 @@ namespace Antelcat.Parameterization.SourceGenerators.Extensions;

public static class NullableExtension
{
/// <summary>
/// 将一个可能为空的转成不可空,如果为null将抛出<see cref="NullReferenceException"/>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t"></param>
/// <returns></returns>
/// <exception cref="NullReferenceException"></exception>
public static T NotNull<T>(this T? t) where T : notnull => t ?? throw new NullReferenceException();
/// <summary>
/// 将一个可能为空的转成不可空,如果为null将抛出<see cref="NullReferenceException"/>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t"></param>
/// <returns></returns>
/// <exception cref="NullReferenceException"></exception>
public static T NotNull<T>(this T? t) where T : notnull => t ?? throw new NullReferenceException();

/// <summary>
/// 将一个可能为空的转成不可空,如果为null将抛出<see cref="NullReferenceException"/>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TException"></typeparam>
/// <param name="t"></param>
/// <returns></returns>
/// <exception cref="NullReferenceException"></exception>
public static T NotNull<T, TException>(this T? t)
where T : notnull where TException : Exception, new() => t ?? throw new TException();
/// <summary>
/// 将一个可能为空的转成不可空,如果为null将抛出<see cref="NullReferenceException"/>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TException"></typeparam>
/// <param name="t"></param>
/// <returns></returns>
/// <exception cref="NullReferenceException"></exception>
public static T NotNull<T, TException>(this T? t)
where T : notnull where TException : Exception, new() => t ?? throw new TException();

/// <summary>
/// 将一个可能为空的转成不可空,如果为null将抛出<see cref="NullReferenceException"/>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t"></param>
/// <returns></returns>
/// <exception cref="NullReferenceException"></exception>
public static T NotNull<T>(this object? t) where T : notnull => (T?)t ?? throw new NullReferenceException();
/// <summary>
/// 将一个可能为空的转成不可空,如果为null将抛出<see cref="NullReferenceException"/>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t"></param>
/// <returns></returns>
/// <exception cref="NullReferenceException"></exception>
public static T NotNull<T>(this object? t) where T : notnull => (T?)t ?? throw new NullReferenceException();

/// <summary>
/// 将一个可能为空的转成不可空,如果为null将抛出<see cref="NullReferenceException"/>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t"></param>
/// <param name="errorMessage"></param>
/// <returns></returns>
/// <exception cref="NullReferenceException"></exception>
public static T NotNull<T>(this T? t, string errorMessage) =>
t ?? throw new NullReferenceException(errorMessage);
/// <summary>
/// 将一个可能为空的转成不可空,如果为null将抛出<see cref="NullReferenceException"/>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t"></param>
/// <param name="errorMessage"></param>
/// <returns></returns>
/// <exception cref="NullReferenceException"></exception>
public static T NotNull<T>(this T? t, string errorMessage) =>
t ?? throw new NullReferenceException(errorMessage);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

public static class StringExtension
{
public static string Escape(this string? s)
{
return s == null ? "null" : $"\"{s.Replace("\"", "\\\"")}\"";
}
public static string Escape(this string? s)
{
return s == null ? "null" : $"\"{s.Replace("\"", "\\\"")}\"";
}
}
Loading

0 comments on commit 7a556c3

Please sign in to comment.