TeamCity.CSharpInteractive/Properties.cs (68 lines of code) (raw):
// ReSharper disable ClassNeverInstantiated.Global
namespace TeamCity.CSharpInteractive;
using System.Collections;
using System.Diagnostics.CodeAnalysis;
using HostApi;
internal class Properties : IProperties
{
private readonly ILog<Properties> _log;
private readonly Dictionary<string, string> _props;
public Properties(
ILog<Properties> log,
ISettings settings)
{
_log = log;
_props = new Dictionary<string, string>(FilterPairs(settings.ScriptProperties));
}
public int Count
{
get
{
lock (_props)
{
return _props.Count;
}
}
}
public string this[string key]
{
get => TryGetValue(key, out var value) ? value : string.Empty;
set
{
lock (_props)
{
_log.Trace(() => new[] {new Text($"Props[\"{key}\"]=\"{value}\"")});
if (!string.IsNullOrEmpty(value))
{
_props[key] = value;
}
else
{
_log.Trace(() => new[] {new Text($"Props.Remove(\"{key}\")")});
_props.Remove(key);
}
}
}
}
public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
{
IReadOnlyList<KeyValuePair<string, string>> props;
lock (_props)
{
props = FilterPairs(_props).ToList().AsReadOnly();
}
return props.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public bool TryGetValue(string key, [MaybeNullWhen(false)] out string value)
{
lock (_props)
{
_props.TryGetValue(key, out var curValue);
value = curValue ?? string.Empty;
_log.Trace(() => new[] {new Text($"Props[\"{key}\"] returns \"{curValue ?? "empty"}\"")});
return !string.IsNullOrEmpty(value);
}
}
private static IEnumerable<KeyValuePair<string, string>> FilterPairs(IEnumerable<KeyValuePair<string, string>> pairs) =>
pairs.Where(i => !string.IsNullOrWhiteSpace(i.Key) && !string.IsNullOrEmpty(i.Value));
}