1 #Region "Microsoft.VisualBasic::d0bd8ff98c817e8b3ab04032760e6d74, Microsoft.VisualBasic.Core\CommandLine\CLIMapper.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Module CLIMapper
35     
36     '         FunctionGetName, Maps
37     
38     
39     ' /********************************************************************************/
40
41 #End Region
42
43 Imports System.Reflection
44 Imports System.Runtime.CompilerServices
45 Imports Microsoft.VisualBasic.CommandLine.Reflection
46
47 Namespace CommandLine
48
49     ''' <summary>
50     ''' 从可写属性之中赋值
51     ''' </summary>
52     Public Module CLIMapper
53
54         ''' <summary>
55         ''' Assign the argument value in the commandline into the target argument container object.
56         ''' The properties in the container class type needs decorating with attribute
57         ''' 
58         ''' (这个拓展函数是将命令行对象反序列化为参数对象)
59         ''' <see cref="Argv"/>
60         ''' </summary>
61         ''' <typeparam name="T"></typeparam>
62         ''' <param name="args"></param>
63         ''' <param name="strict"></param>
64         ''' <returns></returns>
65         <Extension>
66         Public Function Maps(Of T As Class)(args As CommandLine, Optional strict As Boolean = FalseAs T
67             Dim type As Type = GetType(T)
68             Dim obj As Object = Activator.CreateInstance(type)
69             Dim props = From prop As PropertyInfo
70                         In type.GetProperties
71                         Where prop.CanWrite AndAlso
72                             Scripting.IsPrimitive(prop.PropertyType)
73                         Select prop
74
75             For Each prop As PropertyInfo In props
76                 Dim name As String = prop.GetName
77
78                 If Not args.ContainsParameter(name, Not strict) Then
79                     Continue For
80                 Else
81                     type = prop.PropertyType
82                 End If
83
84                 If type.Equals(GetType(Boolean)) Then
85                     ' 由于是逻辑值,所以只要存在就是真,不存在就是False
86                     Call prop.SetValue(obj, TrueNothing)
87                 Else
88                     Dim s As String = args(name)
89                     Dim value = Scripting.CTypeDynamic(s, type)
90
91                     Call prop.SetValue(obj, value, Nothing)
92                 End If
93             Next
94
95             Return DirectCast(obj, T)
96         End Function
97
98         ''' <summary>
99         ''' If the property <paramref name="prop"/> have the custom attribute <see cref="Argv"/>
100         ''' then the name value in <see cref="Argv"/> will be used, otherwise, 
101         ''' <see cref="PropertyInfo.Name"/> will be used. 
102         ''' </summary>
103         ''' <param name="prop"></param>
104         ''' <returns></returns>
105         <Extension> Public Function GetName(prop As PropertyInfo) As String
106             Dim attr As Argv = prop.GetAttribute(Of Argv)
107
108             If attr Is Nothing OrElse attr.Name.StringEmpty Then
109                 Return prop.Name
110             Else
111                 Return attr.Name
112             End If
113         End Function
114     End Module
115 End Namespace