using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.Serialization;
namespace GitHub.DistributedTask.ObjectTemplating
{
///
/// Provides information about an error which occurred during validation.
///
[DataContract]
[EditorBrowsable(EditorBrowsableState.Never)]
public sealed class TemplateValidationErrors : IEnumerable
{
public TemplateValidationErrors()
{
}
public TemplateValidationErrors(
Int32 maxErrors,
Int32 maxMessageLength)
{
m_maxErrors = maxErrors;
m_maxMessageLength = maxMessageLength;
}
public Int32 Count => m_errors.Count;
public void Add(String message)
{
Add(new TemplateValidationError(message));
}
public void Add(Exception ex)
{
Add(null, ex);
}
public void Add(String messagePrefix, Exception ex)
{
for (int i = 0; i < 50; i++)
{
String message = !String.IsNullOrEmpty(messagePrefix) ? $"{messagePrefix} {ex.Message}" : ex.ToString();
Add(new TemplateValidationError(message));
if (ex.InnerException == null)
{
break;
}
ex = ex.InnerException;
}
}
public void Add(IEnumerable errors)
{
foreach (var error in errors)
{
Add(error);
}
}
public void Add(TemplateValidationError error)
{
// Check max errors
if (m_maxErrors <= 0 ||
m_errors.Count < m_maxErrors)
{
// Check max message length
if (m_maxMessageLength > 0 &&
error.Message?.Length > m_maxMessageLength)
{
error = new TemplateValidationError(error.Code, error.Message.Substring(0, m_maxMessageLength) + "[...]");
}
m_errors.Add(error);
}
}
///
/// Throws if any errors.
///
public void Check()
{
if (m_errors.Count > 0)
{
throw new TemplateValidationException(m_errors);
}
}
///
/// Throws if any errors.
/// The error message prefix
///
public void Check(String prefix)
{
if (String.IsNullOrEmpty(prefix))
{
this.Check();
}
else if (m_errors.Count > 0)
{
var message = $"{prefix.Trim()} {String.Join(",", m_errors.Select(e => e.Message))}";
throw new TemplateValidationException(message, m_errors);
}
}
public void Clear()
{
m_errors.Clear();
}
public IEnumerator GetEnumerator()
{
return (m_errors as IEnumerable).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return (m_errors as IEnumerable).GetEnumerator();
}
private readonly List m_errors = new List();
private readonly Int32 m_maxErrors;
private readonly Int32 m_maxMessageLength;
}
}