/// <summary> /// Test if parameter is a key. /// </summary> /// <param name="argument"></param> /// <param name="occuranceIndex"></param> /// <returns>false if <paramref name="argument"/> is a key</returns> public bool QualifyArgument(ILineArgument argument, int occuranceIndex) { if (argument is ILineArgument <ILineHint, string, string> lineHint) { return(true); } if (argument is ILineArgument <ILineCanonicalKey, string, string> lineCanonicalKey) { return(false); } if (argument is ILineArgument <ILineNonCanonicalKey, string, string> lineNonCanonicalKey) { return(false); } if (argument is ILineArgument <ILineParameter, string, string> lineParameter) { IParameterInfo pi; if (ParameterInfos.TryGetValue(lineParameter.Argument0, out pi)) { if (typeof(ILineKey).Equals(pi.InterfaceType) || typeof(ILineCanonicalKey).Equals(pi.InterfaceType) || typeof(ILineNonCanonicalKey).Equals(pi.InterfaceType)) { return(false); } } } return(true); }
/// <summary> /// Append new <see cref="ILine"/> with <paramref name="arguments"/>. /// </summary> /// <param name="line"></param> /// <param name="arguments"></param> /// <returns>Part</returns> /// <exception cref="ArgumentNullException">If appender is null</exception> /// <exception cref="LineException">If append failed</exception> public static ILine Append(this ILine line, ILineArgument arguments) { ILine result; if (line.GetAppender().TryCreate(line, arguments, out result)) { return(result); } throw new LineException(arguments, $"Could not append."); }
public bool TryCreate(ILineFactory factory, ILine previous, ILineArgument arguments, out ILine line) { ILine result = previous; foreach (var f in factories) { if (!f.TryCreate(factory, result, arguments, out result)) { line = default; return(false); } } line = result; return(true); }
/// <summary> /// /// </summary> /// <param name="argument"></param> /// <param name="occuranceIndex"></param> /// <returns></returns> public bool QualifyArgument(ILineArgument argument, int occuranceIndex = -1) { if (argument is ILineArgument <ILineParameter, string, string> parameter) { return(parameter.Argument0 != "Culture"); } if (argument is ILineArgument <ILineNonCanonicalKey, string, string> key) { return(key.Argument0 != "Culture"); } if (argument is ILineArgument <ILineCulture, CultureInfo> culture) { return(false); } return(true); }
/// <summary> /// Create line (part) with <paramref name="arguments"/>. /// </summary> /// <param name="factory"></param> /// <param name="previous"></param> /// <param name="arguments"></param> /// <returns>appended part</returns> /// <exception cref="LineException">If append failed due to unexpected reason</exception> public static ILine Create(this ILineFactory factory, ILine previous, ILineArgument arguments) { ILine result = null; if (factory.TryCreate(previous, arguments, out result)) { return(result); } ILineFactoryByArgument argumentAdapter; if (LineFactoryByArgumentAdapter.Default.TryGet(arguments.GetType(), out argumentAdapter) && argumentAdapter.TryCreate(factory, previous, arguments, out result)) { return(result); } throw new LineException(arguments, "Could not be appended"); }
public bool TryCreate(ILineFactory factory, ILine previous, ILineArgument arguments, out ILine line) { if (arguments is ILineArgument <Intf> ) { Intf result; if (factory is ILineFactory <Intf> casted && casted.TryCreate(factory, previous, out result)) { line = result; return(true); } ILineFactory <Intf> _casted; if (factory is ILineFactoryCastable castable && ((_casted = castable.Cast <Intf>()) != null) && _casted.TryCreate(factory, previous, out result)) { line = result; return(true); } } line = default; return(false); }
/// <summary> /// Create line (part) with <paramref name="arguments"/>. /// </summary> /// <param name="factory"></param> /// <param name="previous"></param> /// <param name="arguments"></param> /// <param name="line"></param> /// <returns>try if create succeeded</returns> /// <exception cref="LineException">If append failed due to unexpected reason</exception> public static bool TryCreate(this ILineFactory factory, ILine previous, ILineArgument arguments, out ILine line) { if (factory == null) { line = previous; return(false); } if (factory is ILineFactoryByArgument argFactory && argFactory.TryCreate(factory, previous, arguments, out line)) { return(true); } ILineFactoryByArgument argumentAdapter; if (LineFactoryByArgumentAdapter.Default.TryGet(arguments.GetType(), out argumentAdapter) && argumentAdapter.TryCreate(factory, previous, arguments, out line)) { return(true); } line = default; return(false); }
/// <summary> /// Qualify argument /// </summary> /// <param name="argument"></param> /// <param name="occuranceIndex"></param> /// <returns></returns> public bool QualifyArgument(ILineArgument argument, int occuranceIndex = -1) { if (argument is ILineArgument <ILineParameter, string, string> lineParameter) { return(QualifyParameter(lineParameter.Argument0, lineParameter.Argument1, occuranceIndex, typeof(ILineParameter))); } else if (argument is ILineArgument <ILineHint, string, string> lineHint) { return(QualifyParameter(lineHint.Argument0, lineHint.Argument1, occuranceIndex, typeof(ILineHint))); } else if (argument is ILineArgument <ILineCanonicalKey, string, string> lineCanonicalKey) { return(QualifyParameter(lineCanonicalKey.Argument0, lineCanonicalKey.Argument1, occuranceIndex, typeof(ILineCanonicalKey))); } else if (argument is ILineArgument <ILineNonCanonicalKey, string, string> lineNonCanonicalKey) { return(QualifyParameter(lineNonCanonicalKey.Argument0, lineNonCanonicalKey.Argument1, occuranceIndex, typeof(ILineNonCanonicalKey))); } return(true); }
/// <summary> /// Prune out arguments that are disqualified by <paramref name="qualifier"/>. /// </summary> /// <param name="line"></param> /// <param name="qualifier">Argument qualifier that is used for determining which parts to keep in the line</param> /// <param name="lineFactory">(optional) extra line factory</param> /// <returns>a modified <paramref name="line"/></returns> /// <exception cref="LineException"></exception> public static ILine Prune(this ILine line, ILineQualifier qualifier, ILineFactory lineFactory = null) { // Qualified parts to append. Order: tail to root. StructList12 <ILineArgument> list = new StructList12 <ILineArgument>(); ILineArgumentQualifier lineArgumentQualifier = qualifier as ILineArgumentQualifier; // Earliest qualified line part. The start tail, where to start appending qualified parts ILine startTail = line; // Line part's arguments. Order: root to tail StructList8 <ILineArgument> tmp = new StructList8 <ILineArgument>(); // Start tail buffered args. Order: root to tail StructList8 <ILineArgument> startTailArgsBuffer = new StructList8 <ILineArgument>(); // Add parts for (ILine l = line; l != null; l = l.GetPreviousPart()) { tmp.Clear(); if (l is ILineArgumentEnumerable lineArguments) { foreach (ILineArgument lineArgument in lineArguments) { tmp.Add(lineArgument); } } if (l is ILineArgument argument) { tmp.Add(argument); } // Now qualify bool linePartQualifies = true; string parameterName, parameterValue; for (int i = tmp.Count - 1; i >= 0; i--) { ILineArgument a = tmp[i]; bool argumentQualifies = true; if (lineArgumentQualifier != null) { // Qualify as an argument. if (!a.IsNonCanonicalKey()) { argumentQualifies = lineArgumentQualifier.QualifyArgument(a); } // Qualify as non-canonical parameter else if (a.TryGetParameter(out parameterName, out parameterValue)) { // Calculate occurance index int occIx = -1; if (lineArgumentQualifier.NeedsOccuranceIndex) { occIx = 0; for (int j = i - 1; j >= 0; j--) { ILineArgument b = list[j]; string parameterName2, parameterValue2; if (b.TryGetParameter(out parameterName2, out parameterValue2)) { continue; } if (parameterValue2 != null && parameterName == parameterName2) { occIx++; } } } argumentQualifies = lineArgumentQualifier.QualifyArgument(a, occIx); } } if (!argumentQualifies) { tmp.RemoveAt(i); } linePartQualifies &= argumentQualifies; } // This part didn't qualify if (!linePartQualifies) { // Append previous start tail to append args if (startTailArgsBuffer.Count > 0) { for (int i = 0; i < startTailArgsBuffer.Count; i++) { list.Add(startTailArgsBuffer[i]); } startTailArgsBuffer.Clear(); startTail = null; } // Add parts that did qualify to append list for (int i = 0; i < tmp.Count; i++) { list.Add(tmp[i]); } // preceding part might be better for start tail startTail = l.GetPreviousPart(); } else // This part qualified { // Add to start tail buffer, in case preceding startTail fails qualifications for (int i = 0; i < tmp.Count; i++) { startTailArgsBuffer.Add(tmp[i]); } } } // Append qualified parts. ILineFactory appender1 = null; line.TryGetAppender(out appender1); // Nothing qualified, no start, create dummy if (startTail == null && list.Count == 0) { // Create dummy ILineFactory appender2 = null; line.TryGetAppender(out appender2); ILinePart dummy = null; if (lineFactory == null || !lineFactory.TryCreate(null, out dummy)) { if (appender2 == null || !appender2.TryCreate(null, out dummy)) { throw new LineException(line, $"LineFactory doesn't have capability to create {nameof(ILinePart)}"); } } return(dummy); } // Append parts ILine result = startTail; for (int i = list.Count - 1; i >= 0; i--) { ILineArgument arg = list[i]; if (lineFactory == null || !lineFactory.TryCreate(result, arg, out result)) { if (appender1 == null || !appender1.TryCreate(result, arg, out result)) { throw new LineException(line, $"LineFactory doesn't have capability to concat {arg}"); } } } return(result); }
/// <summary> /// Append new <see cref="ILine"/> with <paramref name="arguments"/>. /// </summary> /// <param name="line"></param> /// <param name="arguments"></param> /// <param name="result"></param> /// <returns>Part</returns> /// <exception cref="ArgumentNullException">If appender is null</exception> /// <exception cref="LineException">If append failed</exception> public static bool TryAppend(this ILine line, ILineArgument arguments, out ILine result) => line.GetAppender().TryCreate(line, arguments, out result);
/// <summary> /// Try to resolve parameter into line arguments. /// /// For example parameter "Culture" is resolved to <see cref="ILineArgument"/> that produces <see cref="ILineCulture"/> with <see cref="CultureInfo"/>. /// </summary> /// <param name="resolver"></param> /// <param name="previous">(optional) previous parts</param> /// <param name="parameterName"></param> /// <param name="parameterValue"></param> /// <param name="resolvedLineArgument"></param> /// <returns></returns> public static bool TryResolveParameter(this IResolver resolver, ILine previous, string parameterName, string parameterValue, out ILineArgument resolvedLineArgument) { if (resolver is IParameterResolver parameterResolver) { return(parameterResolver.TryResolveParameter(previous, parameterName, parameterValue, out resolvedLineArgument)); } resolvedLineArgument = default; return(false); }
/// <summary> /// Resolve "Culture" parameter into arguments. /// </summary> /// <param name="previous">(optional)</param> /// <param name="parameterName"></param> /// <param name="parameterValue"></param> /// <param name="resolvedLineArgument"></param> /// <returns></returns> public bool TryResolveParameter(ILine previous, string parameterName, string parameterValue, out ILineArgument resolvedLineArgument) { if (parameterValue != null && parameterValue != "" && parameterName == "Culture") { CultureInfo cultureInfo; if (TryResolve(parameterValue, out cultureInfo)) { resolvedLineArgument = new LineArgument <ILineCulture, CultureInfo>(cultureInfo); return(true); } } resolvedLineArgument = default; return(false); }
/// <summary> /// Resolve "Culture" parameter into arguments. /// </summary> /// <param name="previous">(optional)</param> /// <param name="parameterName"></param> /// <param name="parameterValue"></param> /// <param name="resolvedLineArgument"></param> /// <returns></returns> public bool TryResolveParameter(ILine previous, string parameterName, string parameterValue, out ILineArgument resolvedLineArgument) { if (parameterValue != null && parameterValue != "" && parameterName == "PluralRules") { IPluralRules value; if (TryResolve(parameterValue, out value)) { resolvedLineArgument = new LineArgument <ILinePluralRules, IPluralRules>(value); return(true); } } resolvedLineArgument = default; return(false); }
/// <summary> /// Try to resolve parameter into line arguments. /// </summary> /// <param name="previous">(optional) previous parts</param> /// <param name="parameterName"></param> /// <param name="parameterValue"></param> /// <param name="resolvedLineArgument"></param> /// <returns></returns> public bool TryResolveParameter(ILine previous, string parameterName, string parameterValue, out ILineArgument resolvedLineArgument) { List <IParameterResolver> list = resolversByParameterName.TryGetList(parameterName); if (list != null) { foreach (IParameterResolver resolver in list) { if (resolver.TryResolveParameter(previous, parameterName, parameterValue, out resolvedLineArgument)) { return(true); } } } resolvedLineArgument = default; return(false); }
/// <summary> /// Resolve "StringFormat" and "String" into respective line arguments. /// </summary> /// <param name="previous"></param> /// <param name="parameterName"></param> /// <param name="parameterValue"></param> /// <param name="resolvedLineArgument"></param> /// <returns></returns> public bool TryResolveParameter(ILine previous, string parameterName, string parameterValue, out ILineArgument resolvedLineArgument) { if (parameterValue != null && parameterValue != "") { if (parameterName == "String") { IStringFormat stringFormat = previous.FindStringFormat() ?? CSharpFormat.Default; IString value = stringFormat.Parse(parameterValue); resolvedLineArgument = new LineArgument <ILineString, IString>(value); return(true); } else if (parameterName == "StringFormat") { IStringFormat stringFormat; if (TryResolve(parameterValue, out stringFormat)) { resolvedLineArgument = new LineArgument <ILineStringFormat, IStringFormat>(stringFormat); return(true); } } } resolvedLineArgument = default; return(false); }