/// <summary> /// Initializes a new instance of the <see cref="Identifier" /> class. /// </summary> /// <param name="type">The type of the identifier.</param> /// <param name="sigil">The sigil for the identifier.</param> /// <param name="localpart">The localpart of the identifier.</param> /// <param name="domain">The domain of the identifier.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="localpart" /> is <c>null</c>.</exception> /// <exception cref="ArgumentException"> /// Thrown if <paramref name="localpart" /> is empty or full of whitespace. /// </exception> protected Identifier(IdentifierType type, char sigil, string localpart, ServerName domain) { if (localpart == null) { throw new ArgumentNullException(nameof(localpart)); } if (string.IsNullOrWhiteSpace(localpart)) { throw new ArgumentException("ID cannot have empty localpart", nameof(localpart)); } Type = type; Sigil = sigil; Localpart = localpart.Trim(); Domain = domain; }
/// <summary> /// Initializes a new instance of the <see cref="GroupId" /> class. /// </summary> /// <param name="localpart">The localpart of the group ID (between initial <c>+</c> and first <c>:</c>).</param> /// <param name="domain">The domain of the group ID.</param> public GroupId(string localpart, ServerName domain) : base(IdentifierType.User, SigilMapping[IdentifierType.User], localpart, domain) { }
/// <summary> /// Initializes a new instance of the <see cref="RoomAlias" /> class. /// </summary> /// <param name="localpart">The localpart of the alias.</param> /// <param name="domain">The domain on which the alias lives.</param> public RoomAlias(string localpart, ServerName domain) : base(IdentifierType.User, localpart, domain) { }
/// <summary> /// Initializes a new instance of the <see cref="Identifier" /> class. /// </summary> /// <param name="type">The type of the identifier.</param> /// <param name="localpart">The localpart of the identifier.</param> /// <param name="domain">The domain of the identifier.</param> protected Identifier(IdentifierType type, string localpart, ServerName domain) : this(type, SigilMapping[type], localpart, domain) { }
/// <summary> /// Parses an ID to an appropriate identifier type. /// </summary> /// <param name="id">The raw ID to parse.</param> /// <returns> /// Depending on the input string, one of the following: /// <list type="bullet"> /// <item><description><see cref="UserId" />, if the input string was a user ID.</description></item> /// <item><description><see cref="GroupId" />, if the input string was a group ID.</description></item> /// <item><description><see cref="RoomAlias" />, if the input string was a room alias.</description></item> /// </list> /// If the input string is not a valid ID, an <see cref="ArgumentException" /> will be thrown. /// </returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="id" /> is <c>null</c>.</exception> /// <exception cref="ArgumentException"> /// Thrown if <paramref name="id" /> has an incorrect format. Refer to the exception message for /// more details. /// </exception> protected static Identifier ParseId(string id) { if (id == null) { throw new ArgumentNullException(nameof(id), "ID string cannot be null"); } id = id.Trim(); if (string.IsNullOrWhiteSpace(id)) { throw new ArgumentException("ID cannot be empty or full of whitespace", nameof(id)); } var sigil = id[0]; var validSigil = TypeMapping.TryGetValue(sigil, out var type); if (!validSigil) { throw new ArgumentException("ID must start with a valid sigil character", nameof(id)); } if (!id.Contains(SeparatorString)) { throw new ArgumentException("ID cannot have empty domain", nameof(id)); } var sepIndex = id.IndexOf(Separator); if (sepIndex == 1) { throw new ArgumentException("ID cannot have empty localpart", nameof(id)); } if (sepIndex == id.Length - 1) { throw new ArgumentException("ID cannot have empty domain"); } var localpart = id.Substring(1, sepIndex - 1); if (string.IsNullOrWhiteSpace(localpart)) { throw new ArgumentException("ID cannot have empty localpart", nameof(id)); } var domain = new ServerName(id.Substring(sepIndex + 1)); switch (type) { case IdentifierType.User: return(new UserId(localpart, domain)); case IdentifierType.Group: return(new GroupId(localpart, domain)); case IdentifierType.RoomAlias: return(new RoomAlias(localpart, domain)); default: throw new ArgumentException("ID was not of a supported type", nameof(id)); } }