1 //
2 // Copyright (c) 2010-2024 Antmicro
3 // Copyright (c) 2011-2015 Realtime Embedded
4 //
5 // This file is licensed under the MIT License.
6 // Full license text is available in 'licenses/MIT.txt'.
7 //
8 
9 using System;
10 using System.Linq;
11 using System.Reflection;
12 using Antmicro.Renode.Utilities;
13 
14 namespace Antmicro.Renode.Logging
15 {
16     [Convertible]
17     public sealed class LogLevel : IEquatable<LogLevel>, IComparable<LogLevel>
18     {
19         public static LogLevel Noisy = new LogLevel(Level.Noisy);
20         public static LogLevel Debug = new LogLevel(Level.Debug);
21         public static LogLevel Info = new LogLevel(Level.Info, ConsoleColor.Green);
22         public static LogLevel Warning = new LogLevel(Level.Warning, ConsoleColor.DarkYellow);
23         public static LogLevel Error = new LogLevel(Level.Error, ConsoleColor.Red);
24 
25         private readonly Level type;
26 
27         private enum Level
28         {
29             Noisy = -1,
30             Debug = 0,
31             Info = 1,
32             Warning = 2,
33             Error = 3
34         }
35 
LogLevel()36         static LogLevel()
37         {
38             // static fields of LogLevel type define possible LogLevel values
39             AvailableLevels = typeof(LogLevel).GetFields(BindingFlags.Public | BindingFlags.Static).Where(x => x.FieldType.Equals(typeof(LogLevel)))
40                 .Select(x => (LogLevel)x.GetValue(null)).ToArray();
41         }
42 
43         public static LogLevel[] AvailableLevels { get; private set; }
44 
45         public int NumericLevel { get; private set; }
46 
ToString()47         public override string ToString()
48         {
49             return type.ToString().ToUpper();
50         }
51 
ToStringCamelCase()52         public string ToStringCamelCase()
53         {
54             return type.ToString();
55         }
56 
ThisAndHigher()57         public LogLevel[] ThisAndHigher()
58         {
59             return AvailableLevels.Where(l => l.type >= type).ToArray();
60         }
61 
62         public ConsoleColor? Color { get; private set; }
63 
operator <(LogLevel first, LogLevel second)64         public static bool operator <(LogLevel first, LogLevel second)
65         {
66             return first.type < second.type;
67         }
68 
operator <=(LogLevel first, LogLevel second)69         public static bool operator <=(LogLevel first, LogLevel second)
70         {
71             return first.type <= second.type;
72         }
73 
operator >(LogLevel first, LogLevel second)74         public static bool operator >(LogLevel first, LogLevel second)
75         {
76             return first.type > second.type;
77         }
78 
operator >=(LogLevel first, LogLevel second)79         public static bool operator >=(LogLevel first, LogLevel second)
80         {
81             return first.type >= second.type;
82         }
83 
operator ==(LogLevel first, LogLevel second)84         public static bool operator ==(LogLevel first, LogLevel second)
85         {
86             if(Object.ReferenceEquals(null, first) ^ Object.ReferenceEquals(null, second))
87                 return false;
88             if(Object.ReferenceEquals(null, first) && Object.ReferenceEquals(null, second))
89             {
90                 return true;
91             }
92             return first.type == second.type;
93         }
94 
operator !=(LogLevel first, LogLevel second)95         public static bool operator !=(LogLevel first, LogLevel second)
96         {
97             return !(first == second);
98         }
99 
100         // parse is not case sensitive
TryParse(string type, out LogLevel logLevel)101         public static bool TryParse(string type, out LogLevel logLevel)
102         {
103             logLevel = AvailableLevels.FirstOrDefault(x => string.Compare(type, x.ToString(), StringComparison.OrdinalIgnoreCase) == 0);
104             return logLevel != null;
105         }
106 
TryToCreateFromInteger(int level, out LogLevel logLevel)107         public static bool TryToCreateFromInteger(int level, out LogLevel logLevel)
108         {
109             logLevel = AvailableLevels.FirstOrDefault(x => x.NumericLevel == level);
110             if(logLevel == null)
111             {
112                 return false;
113             }
114             return true;
115         }
116 
Parse(string type)117         public static LogLevel Parse(string type)
118         {
119             LogLevel result;
120             if(!TryParse(type, out result))
121             {
122                 throw new FormatException(string.Format("Cannot parse value '{0}' to correct log level.", type));
123             }
124             return result;
125         }
126 
operator LogLevel(string type)127         public static explicit operator LogLevel(string type)
128         {
129             return Parse(type);
130         }
131 
operator LogLevel(int level)132         public static explicit operator LogLevel(int level)
133         {
134             LogLevel logLevel;
135             if(!TryToCreateFromInteger(level, out logLevel))
136             {
137                 throw new InvalidCastException(string.Format("Cannot convert from level {0} to correct log level.", level));
138             }
139             return logLevel;
140         }
141 
operator int(LogLevel type)142         public static explicit operator int(LogLevel type)
143         {
144             return type.NumericLevel;
145         }
146 
LogLevel(Level type, ConsoleColor? color = null)147         private LogLevel(Level type, ConsoleColor? color = null)
148         {
149             this.type = type;
150             this.Color = color;
151             NumericLevel = (int)type;
152         }
153 
Equals(LogLevel other)154         public bool Equals(LogLevel other)
155         {
156             if(other != null)
157                 return this.type == other.type;
158             return false;
159         }
160 
Equals(object obj)161         public override bool Equals(object obj)
162         {
163             var log = obj as LogLevel;
164             if(log != null)
165                 return Equals(log);
166             return false;
167         }
168 
CompareTo(LogLevel other)169         public int CompareTo(LogLevel other)
170         {
171             return type.CompareTo(other.type);
172         }
173 
GetHashCode()174         public override int GetHashCode()
175         {
176             return type.GetHashCode();
177         }
178 
179     }
180 }
181 
182