Files

243 lines
7.2 KiB
C#

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Sarand.Net.Standard.Base.App;
using Sarand.Net.Standard.Base.Core;
using Sarand.Net.Standard.Base.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
namespace Sarand.Net.Standard.Base.Bus
{
//=======================================================================
//[Serializable()]
[JsonConverter(typeof(SysIdJsonConverter))]
public class SysId
{
//-------------------------------------------------------------------
// Data members.
private Int64 id = 0;
//-------------------------------------------------------------------
// Construction.
public SysId() { }
public SysId(Int64? id)
{
this.id = id ?? 0;
}
public SysId(Int32? id)
{
this.id = id ?? 0;
}
//-------------------------------------------------------------------
// Properties - for serialisation.
//[XmlAttribute]
public Int64 Id
{
get { return id; }
set
{
if (id != 0 && value != 0 && value != id) throw new NotSupportedException("SysId value cannot be changed once valid");
id = value;
}
}
//-------------------------------------------------------------------
// Utilities.
public static bool IsValid(SysId sysId)
{
return sysId != null && sysId.id != 0;
}
public static SysId OnInvalid(SysId sysId, SysId sysIdDefault)
{
return IsValid(sysId) ? sysId : sysIdDefault;
}
public static SysId InvalidOnNull(SysId sysId)
{
return sysId ?? new SysId();
}
//-------------------------------------------------------------------
// Comparison.
public override bool Equals(object obj)
{
if (obj == null) return false;
return Equals(obj as SysId);
}
public bool Equals(SysId sysId)
{
if (sysId == null) return false;
// False if either value invalid.
if (id == 0) return false;
return ToInt().Equals(InvalidOnNull(sysId).ToInt());
}
public override int GetHashCode()
{
return id.GetHashCode();
}
//-------------------------------------------------------------------
// Conversion.
public Int64 ToLong()
{
return ToInt(this);
}
public Int32 ToInt()
{
return ToInt(this);
}
public override String ToString()
{
return ToString(this);
}
public String ToString(String invalidValue)
{
return ToString(this, invalidValue);
}
// Null-safe static versions.
public static Int32 ToInt(SysId sysId)
{
return (IsValid(sysId) ? (Int32)sysId.id : 0);
}
public static Int64 ToLong(SysId sysId)
{
return (IsValid(sysId) ? sysId.id : 0);
}
public static String ToString(SysId sysId)
{
return ToString(sysId, String.Empty);
}
public static String ToString(SysId sysId, String invalidValue)
{
return (IsValid(sysId) ? sysId.id.ToString() : invalidValue);
}
// From String.
public static SysId ToSysId(String value)
{
return new SysId(StringUtil.ToLong(value));
}
//-------------------------------------------------------------------
/// <summary>
/// JSON Converter to serialise/deserialise SysId to/from simple integer value.
/// </summary>
class SysIdJsonConverter : JsonConverter<SysId>
{
public override void WriteJson(JsonWriter writer, [AllowNull] SysId id, JsonSerializer serializer)
{
if (id == null) return;
// Simply return the integer Id value.
serializer.Serialize(writer, id.Id);
}
public override SysId ReadJson(JsonReader reader, Type objectType, [AllowNull] SysId existingValue, bool hasExistingValue, JsonSerializer serializer)
{
try
{
// Convert the integer value to a SysId.
if (reader.Value == null) return new SysId();
JValue jValue = new JValue(reader.Value);
return new SysId((long)jValue);
}
catch (Exception exc)
{
SaLogger.Debug($"{SysUtil.Fn} {ExceptionUtil.GetErrorStateMessage(exc)}");
}
return null;
}
}
//-------------------------------------------------------------------
}
//=======================================================================
public static class SysIdCollection
{
//-------------------------------------------------------------------
// List contents.
public static int GetIdCount(this List<SysId> values, bool ignoreInvalid = true, bool ignoreDuplicates = true)
{
if (ignoreDuplicates)
{
values = values.Select(id => id).Distinct().ToList();
// SysId.Equals treats invalid ids as inequal so 'Distinct' doesn't remove them.
if (values.FindIndex(id => !SysId.IsValid(id)) >= 0)
{
// Remove all invalid entries and put one back to correct the count.
values.RemoveAll(id => !SysId.IsValid(id));
values.Add(new SysId());
}
}
return values.Count(id => !ignoreInvalid || SysId.IsValid(id));
}
public static bool HasValidIds(this ICollection<SysId> values)
{
return values.Any(id => SysId.IsValid(id));
}
public static bool Equals(this ICollection<SysId> values, List<SysId> values2)
{
return values.OrderBy(id => id.Id).SequenceEqual(values2.OrderBy(id => id.Id));
}
//-------------------------------------------------------------------
// Populate list.
/// <summary>
/// Add the Id to the list.
/// <para>- Option to ignore invalid Id. [default: true]</para>
/// <para>- Option to ignore duplicate Id. [default: true]</para>
/// </summary>
public static void AddId(this ICollection<SysId> values, SysId sysId, bool ignoreInvalid = true, bool ignoreDuplicates = true)
{
if (ignoreInvalid && !SysId.IsValid(sysId)) return;
if (ignoreDuplicates && values.Contains(sysId)) return;
values.Add(sysId);
}
/// <summary>
/// Add the Ids to the list.
/// <para>- Option to ignore invalid Ids. [default: true]</para>
/// <para>- Option to ignore duplicate Ids. [default: true]</para>
/// </summary>
public static void AddIds(this ICollection<SysId> values, IEnumerable<SysId> sysIds, bool ignoreInvalid = true, bool ignoreDuplicates = true)
{
foreach (SysId id in sysIds)
values.AddId(id, ignoreInvalid, ignoreDuplicates);
}
//-------------------------------------------------------------------
// Extract from list.
/// <summary>Remove specified number of entries from the list and return them.</summary>
/// <returns></returns>
public static List<SysId> ExtractIds(this List<SysId> values, int numberToRemove)
{
List<SysId> ids = new List<SysId>();
while (values.Count > 0 && ids.Count < numberToRemove)
{
SysId id = values.ElementAt(0);
values.RemoveAt(0);
ids.Add(id);
}
return ids;
}
//-------------------------------------------------------------------
/// <summary>
/// Combine items in list as a delimited string.
/// </summary>
/// <param name="values"></param>
/// <param name="delimiter"></param>
/// <param name="ignoreInvalid"></param>
/// <returns></returns>
public static String Concat(this ICollection<SysId> values, String delimiter, bool ignoreInvalid = true)
{
HashSet<String> ids = new HashSet<string>();
foreach (SysId id in values.Where(id => !ignoreInvalid || SysId.IsValid(id)))
ids.Add(id.ToString());
return ids.Concat(delimiter);
}
//-------------------------------------------------------------------
}
//=======================================================================
}