Forked from thedavecarroll/Part1-ConvertTo-ClassDefinition.ps1
Created
May 30, 2023 13:35
-
-
Save mavaddat/8531888f51fa606887d55a1ab9193767 to your computer and use it in GitHub Desktop.
Creating a Class Definition from an Existing Object - Ironscripter Challenge
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Requires -Version 5.1 | |
function ConvertTo-ClassDefinition { | |
param( | |
[Parameter(Position = 0, Mandatory, ValueFromPipeline)] | |
[object]$Object, | |
[ValidateNotNullOrEmpty()] | |
[string]$ClassName, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Include')] | |
[string[]]$IncludeProperty = '*', | |
[ValidateNotNullOrEmpty()] | |
[Alias('Exclude')] | |
[string[]]$ExcludeProperty | |
) | |
# get the immediate object type | |
$ObjectType = $Object.psobject.TypeNames[0] | |
# set the name of the class | |
if ($ClassName) { | |
$BaseClassName = $ClassName | |
} else { | |
$BaseClassName = "My" + $ObjectType | |
} | |
# get properties | |
if ($IncludeProperty -ne '*') { | |
$Properties = $Object.psobject.properties | Where-Object { | |
$_.Name -in $IncludeProperty -and | |
$_.Name -notin $ExcludeProperty | |
} | |
} else { | |
$Properties = $Object.psobject.properties | Where-Object { | |
$_.Name -notin $ExcludeProperty | |
} | |
} | |
# create stringbuilder | |
$Indent = ' ' * 4 | |
$ClassDefinition = [StringBuilder]::new() | |
[void]$ClassDefinition.AppendLine(('# class definition created by {0} at {1} for object type {2}' -f $MyInvocation.MyCommand,(Get-Date),$ObjectType)) | |
[void]$ClassDefinition.AppendLine('') | |
[void]$ClassDefinition.AppendLine(('class {0} {{' -f $BaseClassName )) | |
[void]$ClassDefinition.AppendLine('') | |
# add all properties | |
[void]$ClassDefinition.AppendLine(('{0}# properties' -f $Indent)) | |
foreach ($Property in $Properties) { | |
[void]$ClassDefinition.AppendLine(('{0}[{1}]${2}' -f $Indent,$Property.TypeNameOfValue,$Property.Name)) | |
} | |
[void]$ClassDefinition.AppendLine('') | |
# add simple constructors | |
[void]$ClassDefinition.AppendLine(('{0}# constructors' -f $Indent)) | |
[void]$ClassDefinition.AppendLine(('{0}{1} () {{ }}' -f $Indent,$BaseClassName)) | |
[void]$ClassDefinition.AppendLine(('{0}{1} ([{2}]$InputObject) {{' -f $Indent,$BaseClassName,$ObjectType)) | |
foreach ($Property in $Properties) { | |
[void]$ClassDefinition.AppendLine(('{0}{0}$this.{1} = $InputObject.{1}' -f $Indent,$Property.Name)) | |
} | |
[void]$ClassDefinition.AppendLine(('{0}}}' -f $Indent)) | |
[void]$ClassDefinition.AppendLine('') | |
# end class | |
[void]$ClassDefinition.AppendLine('}') | |
# output class definition | |
$ClassDefinition.ToString() | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# class definition created by ConvertTo-ClassDefinition at 1/30/2021 11:55:19 AM for object type PSCustomObject | |
class BluebirdPS { | |
# properties | |
[System.Int64]$Id | |
hidden [String]$IdStr | |
[String]$Name | |
[String]$ScreenName | |
[String]$Location | |
[System.Object]$ProfileLocation | |
[String]$Description | |
[Uri]$Url | |
[PSCustomObject]$Entities | |
[System.Boolean]$Protected | |
[System.Int64]$FollowersCount | |
[System.Int64]$FriendsCount | |
[System.Int64]$ListedCount | |
[DateTime]$CreatedAt | |
[System.Int64]$FavouritesCount | |
[System.Object]$UtcOffset | |
[System.Object]$TimeZone | |
[System.Boolean]$GeoEnabled | |
[System.Boolean]$Verified | |
[System.Int64]$StatusesCount | |
[System.Object]$Lang | |
[PSCustomObject]$Status | |
[System.Boolean]$ContributorsEnabled | |
[System.Boolean]$IsTranslator | |
[System.Boolean]$IsTranslationEnabled | |
[String]$ProfileBackgroundColor | |
[Uri]$ProfileBackgroundImageUrl | |
[Uri]$ProfileBackgroundImageUrlHttps | |
[System.Boolean]$ProfileBackgroundTile | |
[Uri]$ProfileImageUrl | |
[Uri]$ProfileImageUrlHttps | |
[Uri]$ProfileBannerUrl | |
[String]$ProfileLinkColor | |
[String]$ProfileSidebarBorderColor | |
[String]$ProfileSidebarFillColor | |
[String]$ProfileTextColor | |
[System.Boolean]$ProfileUseBackgroundImage | |
[System.Boolean]$HasExtendedProfile | |
[System.Boolean]$DefaultProfile | |
[System.Boolean]$DefaultProfileImage | |
[System.Boolean]$Following | |
[System.Boolean]$FollowRequestSent | |
[System.Boolean]$Notifications | |
[String]$TranslatorType | |
[System.Boolean]$Suspended | |
[System.Boolean]$NeedsPhoneVerification | |
# constructors | |
BluebirdPS () { } | |
BluebirdPS ([PSCustomObject]$InputObject) { | |
$this.Id = $InputObject.id | |
$this.IdStr = $InputObject.id_str | |
$this.Name = $InputObject.name | |
$this.ScreenName = $InputObject.screen_name | |
$this.Location = $InputObject.location | |
$this.ProfileLocation = $InputObject.profile_location | |
$this.Description = $InputObject.description | |
$this.Url = $InputObject.url | |
$this.Entities = $InputObject.entities | |
$this.Protected = $InputObject.protected | |
$this.FollowersCount = $InputObject.followers_count | |
$this.FriendsCount = $InputObject.friends_count | |
$this.ListedCount = $InputObject.listed_count | |
$this.CreatedAt = [datetime]::ParseExact($InputObject.created_at,'ddd MMM dd HH:mm:ss zzz yyyy',(Get-Culture)) | |
$this.FavouritesCount = $InputObject.favourites_count | |
$this.UtcOffset = $InputObject.utc_offset | |
$this.TimeZone = $InputObject.time_zone | |
$this.GeoEnabled = $InputObject.geo_enabled | |
$this.Verified = $InputObject.verified | |
$this.StatusesCount = $InputObject.statuses_count | |
$this.Lang = $InputObject.lang | |
$this.Status = $InputObject.status | |
$this.ContributorsEnabled = $InputObject.contributors_enabled | |
$this.IsTranslator = $InputObject.is_translator | |
$this.IsTranslationEnabled = $InputObject.is_translation_enabled | |
$this.ProfileBackgroundColor = $InputObject.profile_background_color | |
$this.ProfileBackgroundImageUrl = $InputObject.profile_background_image_url | |
$this.ProfileBackgroundImageUrlHttps = $InputObject.profile_background_image_url_https | |
$this.ProfileBackgroundTile = $InputObject.profile_background_tile | |
$this.ProfileImageUrl = $InputObject.profile_image_url | |
$this.ProfileImageUrlHttps = $InputObject.profile_image_url_https | |
$this.ProfileBannerUrl = $InputObject.profile_banner_url | |
$this.ProfileLinkColor = $InputObject.profile_link_color | |
$this.ProfileSidebarBorderColor = $InputObject.profile_sidebar_border_color | |
$this.ProfileSidebarFillColor = $InputObject.profile_sidebar_fill_color | |
$this.ProfileTextColor = $InputObject.profile_text_color | |
$this.ProfileUseBackgroundImage = $InputObject.profile_use_background_image | |
$this.HasExtendedProfile = $InputObject.has_extended_profile | |
$this.DefaultProfile = $InputObject.default_profile | |
$this.DefaultProfileImage = $InputObject.default_profile_image | |
$this.Following = $InputObject.following | |
$this.FollowRequestSent = $InputObject.follow_request_sent | |
$this.Notifications = $InputObject.notifications | |
$this.TranslatorType = $InputObject.translator_type | |
$this.Suspended = $InputObject.suspended | |
$this.NeedsPhoneVerification = $InputObject.needs_phone_verification | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Requires -Version 5.1 | |
using namespace System.Management.Automation | |
using namespace System.Text | |
function ConvertTo-ClassDefinition { | |
param( | |
[Parameter(Position = 0, Mandatory, ValueFromPipeline)] | |
[object]$Object, | |
[ValidateNotNullOrEmpty()] | |
[string]$ClassName, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Include')] | |
[string[]]$IncludeProperty = '*', | |
[ValidateNotNullOrEmpty()] | |
[Alias('Exclude')] | |
[string[]]$ExcludeProperty, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Hidden')] | |
[string[]]$HiddenProperty | |
) | |
# get the immediate object type | |
$ObjectTypeBase = $Object.psobject.TypeNames[0] | |
# part 2: correct PSCustomObject input object | |
if ($ObjectTypeBase -match 'PSCustomObject') { | |
$ObjectType = 'PSCustomObject' | |
} else { | |
$ObjectType = $ObjectTypeBase | |
} | |
# set the name of the class | |
# part 2: PascalCase the class name | |
if ($ClassName) { | |
$BaseClassName = $ClassName | ConvertTo-PascalCase | |
} else { | |
$BaseClassName = "My." + $ObjectType | ConvertTo-PascalCase | |
} | |
# get properties | |
if ($IncludeProperty -ne '*') { | |
$Properties = $Object.psobject.properties | Where-Object { | |
$_.Name -in $IncludeProperty -and | |
$_.Name -notin $ExcludeProperty | |
} | |
} else { | |
$Properties = $Object.psobject.properties | Where-Object { | |
$_.Name -notin $ExcludeProperty | |
} | |
} | |
# create stringbuilder | |
$Indent = ' ' * 4 | |
$ClassDefinition = [StringBuilder]::new() | |
[void]$ClassDefinition.AppendLine(('# class definition created by {0} at {1} for object type {2}' -f $MyInvocation.MyCommand,(Get-Date),$ObjectType)) | |
[void]$ClassDefinition.AppendLine('') | |
[void]$ClassDefinition.AppendLine(('class {0} {{' -f $BaseClassName)) | |
[void]$ClassDefinition.AppendLine('') | |
# part 1: add all properties | |
# part 2: create a new stringbuilder for the properties in the constructor so we only have to loop through properties once | |
$ConstructorProperty = [StringBuilder]::new() | |
[void]$ClassDefinition.AppendLine(('{0}# properties' -f $Indent)) | |
foreach ($Property in $Properties) { | |
# part 2: ensure proper PascalCase of the property | |
$PascalCaseProperty = ConvertTo-PascalCase -String $Property.Name | |
# part 2: ensure best guess for string values for PSCustomObject objects | |
$PropertySetter = '$InputObject.{0}' -f $Property.Name | |
if ($Property.TypeNameOfValue -match 'string' -and $ObjectType -eq 'PSCustomObject' ) { | |
$PropertyTypeConversion = Resolve-PropertyType -PropertyValue $Property.Value | |
$PropertyTypeName = $PropertyTypeConversion | Select-Object -First 1 | |
if ('Parse' -in $PropertyTypeConversion) { | |
$PropertySetter = '[datetime]::Parse($InputObject.{0},(Get-Culture))' -f $Property.Name | |
} elseif ('ParseExact' -in $PropertyTypeConversion) { | |
$PropertySetter = '[datetime]::ParseExact($InputObject.{0},''{1}'',(Get-Culture))' -f $Property.Name,$PropertyTypeConversion[2] | |
} | |
} else { | |
if ($Property.TypeNameOfValue -match 'PSCustomObject') { | |
$PropertyTypeName = 'PSCustomObject' | |
} else { | |
$PropertyTypeName = $Property.TypeNameOfValue | |
} | |
} | |
# part 2: if a property needs to be hidden, add that to the property statement | |
if ($Property.Name -in $HiddenProperty -or $PascalCaseProperty -in $HiddenProperty) { | |
$PropertyStatement = '{0}hidden [{1}]${2}' -f $Indent,$PropertyTypeName,$PascalCaseProperty | |
} else { | |
$PropertyStatement = '{0}[{1}]${2}' -f $Indent,$PropertyTypeName,$PascalCaseProperty | |
} | |
[void]$ClassDefinition.AppendLine($PropertyStatement) | |
[void]$ConstructorProperty.AppendLine(('{0}{0}$this.{1} = {2}' -f $Indent,$PascalCaseProperty,$PropertySetter)) | |
} | |
[void]$ClassDefinition.AppendLine('') | |
# add simple constructors | |
[void]$ClassDefinition.AppendLine(('{0}# constructors' -f $Indent)) | |
[void]$ClassDefinition.AppendLine(('{0}{1} () {{ }}' -f $Indent,$BaseClassName)) | |
[void]$ClassDefinition.AppendLine(('{0}{1} ([{2}]$InputObject) {{' -f $Indent,$BaseClassName,$ObjectType)) | |
# part 2: ensure proper PascalCase in the constructor | |
[void]$ClassDefinition.AppendLine($ConstructorProperty.ToString()) | |
[void]$ClassDefinition.AppendLine(('{0}}}' -f $Indent)) | |
[void]$ClassDefinition.AppendLine('') | |
# end class | |
[void]$ClassDefinition.AppendLine('}') | |
# output class definition | |
$ClassDefinition.ToString() | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function ConvertTo-PascalCase { | |
[CmdletBinding()] | |
param( | |
[Parameter(Mandatory,ValueFromPipeline)] | |
[string[]]$String | |
) | |
begin { | |
$Culture = Get-Culture | |
} | |
process { | |
foreach ($Word in $String) { | |
$Words = $Word -split '\W|_' | |
$PascalCase = if ($Words.Count -gt 1) { | |
$Words | ForEach-Object { | |
$Culture.TextInfo.ToTitleCase($_.ToLower()) | |
} | |
} else { | |
if ($Word -cnotmatch '^[A-Z]') { | |
return $Culture.TextInfo.ToTitleCase($Word) | |
} else { | |
return $Word | |
} | |
} | |
} | |
$PascalCase -join '' | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Resolve-PropertyType { | |
[CmdletBinding()] | |
param( | |
[Parameter(Mandatory,ValueFromPipeline)] | |
[string]$PropertyValue | |
) | |
$TwitterDateFormat ='ddd MMM dd HH:mm:ss zzz yyyy' | |
# check for url | |
try { | |
[void][Uri]::new($PropertyValue) | |
return 'Uri' | |
} | |
catch { } # do nothing, continue to next text | |
# check for known date time | |
try { | |
[void][datetime]::Parse($PropertyValue,(Get-Culture)) | |
return 'DateTime','Parse' | |
} | |
catch { } | |
# check for Twitter date time | |
try { | |
[void][datetime]::ParseExact($PropertyValue,$TwitterDateFormat,(Get-Culture)) | |
return 'DateTime','ParseExact',$TwitterDateFormat | |
} | |
catch { } | |
return 'String' | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# class definition created by ConvertTo-ClassDefinition at 2/2/2021 12:19:34 AM for object type PSCustomObject | |
class BluebirdPSUser { | |
# properties | |
hidden [String]$IdStr | |
[String]$Location | |
[String]$ScreenName | |
[System.Int64]$Id | |
[System.Boolean]$DefaultProfile | |
# constructors | |
BluebirdPSUser () { } | |
BluebirdPSUser ([PSCustomObject]$InputObject) { | |
$this.IdStr = $InputObject.id_str | |
$this.Location = $InputObject.location | |
$this.ScreenName = $InputObject.screen_name | |
$this.Id = $InputObject.id | |
$this.DefaultProfile = $InputObject.default_profile | |
} | |
<# original output from ConvertTo-ClassDefinition | |
[OutputTypeName] UpdateProfile ( | |
[TypeName]$Param1, | |
[TypeName]$Param2 | |
) { | |
# your code | |
return $Output | |
} | |
[OutputTypeName] SetLocation ( | |
[TypeName]$Param1, | |
[TypeName]$Param2 | |
) { | |
# your code | |
return $Output | |
} | |
#> | |
# update code | |
[string] UpdateProfile ( ) { | |
return ("Updated Profile for {0}" -f $this.ScreenName) | |
} | |
# update code | |
[bool] SetLocation () { | |
return $false | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# class definition created by ConvertTo-ClassDefinition at 2/2/2021 1:01:11 AM for object type PSCustomObject | |
class BluebirdPSUserStatusRetweetedStatusEntities { | |
# properties | |
[System.Object[]]$Hashtags | |
[System.Object[]]$UserMentions | |
[System.Object[]]$Symbols | |
[System.Object[]]$Urls | |
# constructors | |
BluebirdPSUserStatusRetweetedStatusEntities () { } | |
BluebirdPSUserStatusRetweetedStatusEntities ([PSCustomObject]$InputObject) { | |
$this.Hashtags = $InputObject.hashtags | |
$this.UserMentions = $InputObject.user_mentions | |
$this.Symbols = $InputObject.symbols | |
$this.Urls = $InputObject.urls | |
} | |
} | |
# class definition created by ConvertTo-ClassDefinition at 2/2/2021 1:01:11 AM for object type PSCustomObject | |
class BluebirdPSUserStatusRetweetedStatus { | |
# properties | |
[System.Object]$Contributors | |
[System.Object]$InReplyToUserIdStr | |
[System.Boolean]$PossiblySensitive | |
[String]$Text | |
[System.Object]$Geo | |
[System.Int64]$Id | |
[System.Object]$InReplyToStatusId | |
[System.Boolean]$Truncated | |
[System.Object]$Coordinates | |
[System.Boolean]$IsQuoteStatus | |
[System.Boolean]$Retweeted | |
[System.Object]$InReplyToScreenName | |
[String]$Lang | |
[DateTime]$CreatedAt | |
[System.Int64]$RetweetCount | |
[PSCustomObject]$Entities | |
[System.Object]$InReplyToStatusIdStr | |
[String]$IdStr | |
[System.Boolean]$Favorited | |
[System.Object]$InReplyToUserId | |
[System.Object]$Place | |
[String]$Source | |
[System.Int64]$FavoriteCount | |
# constructors | |
BluebirdPSUserStatusRetweetedStatus () { } | |
BluebirdPSUserStatusRetweetedStatus ([PSCustomObject]$InputObject) { | |
$this.Contributors = $InputObject.contributors | |
$this.InReplyToUserIdStr = $InputObject.in_reply_to_user_id_str | |
$this.PossiblySensitive = $InputObject.possibly_sensitive | |
$this.Text = $InputObject.text | |
$this.Geo = $InputObject.geo | |
$this.Id = $InputObject.id | |
$this.InReplyToStatusId = $InputObject.in_reply_to_status_id | |
$this.Truncated = $InputObject.truncated | |
$this.Coordinates = $InputObject.coordinates | |
$this.IsQuoteStatus = $InputObject.is_quote_status | |
$this.Retweeted = $InputObject.retweeted | |
$this.InReplyToScreenName = $InputObject.in_reply_to_screen_name | |
$this.Lang = $InputObject.lang | |
$this.CreatedAt = [datetime]::ParseExact($InputObject.created_at,'ddd MMM dd HH:mm:ss zzz yyyy',(Get-Culture)) | |
$this.RetweetCount = $InputObject.retweet_count | |
$this.Entities = $InputObject.entities | |
$this.InReplyToStatusIdStr = $InputObject.in_reply_to_status_id_str | |
$this.IdStr = $InputObject.id_str | |
$this.Favorited = $InputObject.favorited | |
$this.InReplyToUserId = $InputObject.in_reply_to_user_id | |
$this.Place = $InputObject.place | |
$this.Source = $InputObject.source | |
$this.FavoriteCount = $InputObject.favorite_count | |
} | |
} | |
# class definition created by ConvertTo-ClassDefinition at 2/2/2021 1:01:11 AM for object type PSCustomObject | |
class BluebirdPSUserStatusEntities { | |
# properties | |
[System.Object[]]$Hashtags | |
[System.Object[]]$UserMentions | |
[System.Object[]]$Symbols | |
[System.Object[]]$Urls | |
# constructors | |
BluebirdPSUserStatusEntities () { } | |
BluebirdPSUserStatusEntities ([PSCustomObject]$InputObject) { | |
$this.Hashtags = $InputObject.hashtags | |
$this.UserMentions = $InputObject.user_mentions | |
$this.Symbols = $InputObject.symbols | |
$this.Urls = $InputObject.urls | |
} | |
} | |
# class definition created by ConvertTo-ClassDefinition at 2/2/2021 1:01:11 AM for object type PSCustomObject | |
class BluebirdPSUserStatus { | |
# properties | |
[System.Object]$Contributors | |
[System.Object]$InReplyToUserIdStr | |
[String]$Text | |
[System.Object]$Geo | |
[System.Int64]$Id | |
[System.Object]$InReplyToStatusId | |
[System.Boolean]$Truncated | |
[System.Object]$Coordinates | |
[PSCustomObject]$RetweetedStatus | |
[System.Boolean]$Retweeted | |
[System.Object]$InReplyToScreenName | |
[String]$Lang | |
[DateTime]$CreatedAt | |
[System.Int64]$RetweetCount | |
[PSCustomObject]$Entities | |
[System.Boolean]$IsQuoteStatus | |
[System.Object]$InReplyToStatusIdStr | |
[String]$IdStr | |
[System.Boolean]$Favorited | |
[System.Object]$InReplyToUserId | |
[System.Object]$Place | |
[String]$Source | |
[System.Int64]$FavoriteCount | |
# constructors | |
BluebirdPSUserStatus () { } | |
BluebirdPSUserStatus ([PSCustomObject]$InputObject) { | |
$this.Contributors = $InputObject.contributors | |
$this.InReplyToUserIdStr = $InputObject.in_reply_to_user_id_str | |
$this.Text = $InputObject.text | |
$this.Geo = $InputObject.geo | |
$this.Id = $InputObject.id | |
$this.InReplyToStatusId = $InputObject.in_reply_to_status_id | |
$this.Truncated = $InputObject.truncated | |
$this.Coordinates = $InputObject.coordinates | |
$this.RetweetedStatus = $InputObject.retweeted_status | |
$this.Retweeted = $InputObject.retweeted | |
$this.InReplyToScreenName = $InputObject.in_reply_to_screen_name | |
$this.Lang = $InputObject.lang | |
$this.CreatedAt = [datetime]::ParseExact($InputObject.created_at,'ddd MMM dd HH:mm:ss zzz yyyy',(Get-Culture)) | |
$this.RetweetCount = $InputObject.retweet_count | |
$this.Entities = $InputObject.entities | |
$this.IsQuoteStatus = $InputObject.is_quote_status | |
$this.InReplyToStatusIdStr = $InputObject.in_reply_to_status_id_str | |
$this.IdStr = $InputObject.id_str | |
$this.Favorited = $InputObject.favorited | |
$this.InReplyToUserId = $InputObject.in_reply_to_user_id | |
$this.Place = $InputObject.place | |
$this.Source = $InputObject.source | |
$this.FavoriteCount = $InputObject.favorite_count | |
} | |
} | |
# class definition created by ConvertTo-ClassDefinition at 2/2/2021 1:01:11 AM for object type PSCustomObject | |
class BluebirdPSUserEntitiesDescription { | |
# properties | |
[System.Object[]]$Urls | |
# constructors | |
BluebirdPSUserEntitiesDescription () { } | |
BluebirdPSUserEntitiesDescription ([PSCustomObject]$InputObject) { | |
$this.Urls = $InputObject.urls | |
} | |
} | |
# class definition created by ConvertTo-ClassDefinition at 2/2/2021 1:01:11 AM for object type PSCustomObject | |
class BluebirdPSUserEntitiesUrl { | |
# properties | |
[System.Object[]]$Urls | |
# constructors | |
BluebirdPSUserEntitiesUrl () { } | |
BluebirdPSUserEntitiesUrl ([PSCustomObject]$InputObject) { | |
$this.Urls = $InputObject.urls | |
} | |
} | |
# class definition created by ConvertTo-ClassDefinition at 2/2/2021 1:01:11 AM for object type PSCustomObject | |
class BluebirdPSUserEntities { | |
# properties | |
[PSCustomObject]$Description | |
[PSCustomObject]$Url | |
# constructors | |
BluebirdPSUserEntities () { } | |
BluebirdPSUserEntities ([PSCustomObject]$InputObject) { | |
$this.Description = $InputObject.description | |
$this.Url = $InputObject.url | |
} | |
} | |
# class definition created by ConvertTo-ClassDefinition at 2/2/2021 1:01:11 AM for object type PSCustomObject | |
class BluebirdPSUser { | |
# properties | |
[System.Boolean]$NeedsPhoneVerification | |
[System.Boolean]$Protected | |
[String]$ProfileBackgroundColor | |
[System.Boolean]$HasExtendedProfile | |
[System.Boolean]$IsTranslationEnabled | |
[Uri]$ProfileBackgroundImageUrl | |
[Uri]$Url | |
[System.Int64]$Id | |
[String]$Description | |
[System.Object]$TimeZone | |
[System.Object]$Lang | |
[System.Boolean]$Suspended | |
[PSCustomObject]$Status | |
[System.Int64]$FavouritesCount | |
[System.Boolean]$ProfileBackgroundTile | |
[System.Boolean]$Verified | |
[System.Boolean]$FollowRequestSent | |
[System.Int64]$ListedCount | |
[System.Boolean]$ProfileUseBackgroundImage | |
[Uri]$ProfileImageUrl | |
[System.Int64]$FriendsCount | |
[String]$ProfileLinkColor | |
[System.Boolean]$GeoEnabled | |
[System.Boolean]$ContributorsEnabled | |
[String]$ProfileSidebarFillColor | |
[String]$Location | |
[System.Boolean]$Notifications | |
[System.Boolean]$DefaultProfile | |
[String]$ProfileTextColor | |
[String]$ScreenName | |
[System.Object]$ProfileLocation | |
[System.Int64]$FollowersCount | |
[String]$Name | |
[System.Boolean]$Following | |
[Uri]$ProfileBannerUrl | |
[String]$TranslatorType | |
[String]$IdStr | |
[System.Object]$UtcOffset | |
[Uri]$ProfileImageUrlHttps | |
[DateTime]$CreatedAt | |
[System.Int64]$StatusesCount | |
[Uri]$ProfileBackgroundImageUrlHttps | |
[PSCustomObject]$Entities | |
[String]$ProfileSidebarBorderColor | |
[System.Boolean]$IsTranslator | |
[System.Boolean]$DefaultProfileImage | |
# constructors | |
BluebirdPSUser () { } | |
BluebirdPSUser ([PSCustomObject]$InputObject) { | |
$this.NeedsPhoneVerification = $InputObject.needs_phone_verification | |
$this.Protected = $InputObject.protected | |
$this.ProfileBackgroundColor = $InputObject.profile_background_color | |
$this.HasExtendedProfile = $InputObject.has_extended_profile | |
$this.IsTranslationEnabled = $InputObject.is_translation_enabled | |
$this.ProfileBackgroundImageUrl = $InputObject.profile_background_image_url | |
$this.Url = $InputObject.url | |
$this.Id = $InputObject.id | |
$this.Description = $InputObject.description | |
$this.TimeZone = $InputObject.time_zone | |
$this.Lang = $InputObject.lang | |
$this.Suspended = $InputObject.suspended | |
$this.Status = $InputObject.status | |
$this.FavouritesCount = $InputObject.favourites_count | |
$this.ProfileBackgroundTile = $InputObject.profile_background_tile | |
$this.Verified = $InputObject.verified | |
$this.FollowRequestSent = $InputObject.follow_request_sent | |
$this.ListedCount = $InputObject.listed_count | |
$this.ProfileUseBackgroundImage = $InputObject.profile_use_background_image | |
$this.ProfileImageUrl = $InputObject.profile_image_url | |
$this.FriendsCount = $InputObject.friends_count | |
$this.ProfileLinkColor = $InputObject.profile_link_color | |
$this.GeoEnabled = $InputObject.geo_enabled | |
$this.ContributorsEnabled = $InputObject.contributors_enabled | |
$this.ProfileSidebarFillColor = $InputObject.profile_sidebar_fill_color | |
$this.Location = $InputObject.location | |
$this.Notifications = $InputObject.notifications | |
$this.DefaultProfile = $InputObject.default_profile | |
$this.ProfileTextColor = $InputObject.profile_text_color | |
$this.ScreenName = $InputObject.screen_name | |
$this.ProfileLocation = $InputObject.profile_location | |
$this.FollowersCount = $InputObject.followers_count | |
$this.Name = $InputObject.name | |
$this.Following = $InputObject.following | |
$this.ProfileBannerUrl = $InputObject.profile_banner_url | |
$this.TranslatorType = $InputObject.translator_type | |
$this.IdStr = $InputObject.id_str | |
$this.UtcOffset = $InputObject.utc_offset | |
$this.ProfileImageUrlHttps = $InputObject.profile_image_url_https | |
$this.CreatedAt = [datetime]::ParseExact($InputObject.created_at,'ddd MMM dd HH:mm:ss zzz yyyy',(Get-Culture)) | |
$this.StatusesCount = $InputObject.statuses_count | |
$this.ProfileBackgroundImageUrlHttps = $InputObject.profile_background_image_url_https | |
$this.Entities = $InputObject.entities | |
$this.ProfileSidebarBorderColor = $InputObject.profile_sidebar_border_color | |
$this.IsTranslator = $InputObject.is_translator | |
$this.DefaultProfileImage = $InputObject.default_profile_image | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Requires -Version 5.1 | |
using namespace System.Management.Automation | |
using namespace System.Text | |
function ConvertTo-ClassDefinition { | |
param( | |
[Parameter(Position = 0, Mandatory, ValueFromPipeline)] | |
[object]$Object, | |
[ValidateNotNullOrEmpty()] | |
[string]$ClassName, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Include')] | |
[string[]]$IncludeProperty = '*', | |
[ValidateNotNullOrEmpty()] | |
[Alias('Exclude')] | |
[string[]]$ExcludeProperty, | |
[ValidateNotNullOrEmpty()] | |
[Alias('Hidden')] | |
[string[]]$HiddenProperty, | |
[ValidateNotNullOrEmpty()] | |
[string[]]$Method, | |
[switch]$NoComments, | |
[switch]$PassThru | |
) | |
# get the immediate object type | |
$ObjectTypeBase = $Object.psobject.TypeNames[0] | |
# part 2: correct PSCustomObject input object | |
if ($ObjectTypeBase -match 'PSCustomObject') { | |
$ObjectType = 'PSCustomObject' | |
} else { | |
$ObjectType = $ObjectTypeBase | |
} | |
# set the name of the class | |
# part 2: PascalCase the class name | |
if ($ClassName) { | |
$BaseClassName = $ClassName | ConvertTo-PascalCase | |
} else { | |
$BaseClassName = "My." + $ObjectType | ConvertTo-PascalCase | |
} | |
# huge bugfix: original property names or PascalCase property names should be allowed for included and excluded properties. | |
$PascalCaseProperties = @{} | |
$Object.psobject.properties | ForEach-Object { | |
$PascalCaseProperties.Add((ConvertTo-PascalCase -String $_.Name),$_) | |
} | |
if ($IncludeProperty -ne '*') { | |
$IncludeProperties = $PascalCaseProperties.Keys | Where-Object { | |
($_ -in $IncludeProperty -or $PascalCaseProperties[$_].Name -in $IncludeProperty) | |
} | |
} else { | |
$IncludeProperties = $PascalCaseProperties.Keys | |
} | |
if ($ExcludeProperty) { | |
$ExcludeProperties = $PascalCaseProperties.Keys | Where-Object { | |
($_ -in $ExcludeProperty -or $PascalCaseProperties[$_].Name -in $ExcludeProperty) | |
} | |
} | |
if ($ExcludeProperties) { | |
$Properties = Compare-Object -ReferenceObject $IncludeProperties -DifferenceObject $ExcludeProperties -PassThru | Where-Object { $_.SideIndicator -eq '<=' } | |
} else { | |
$Properties = $IncludeProperties | |
} | |
# create stringbuilder | |
$Indent = ' ' * 4 | |
$ClassDefinition = [StringBuilder]::new() | |
if (-Not $PSBoundParameters.ContainsKey('NoComments')) { | |
[void]$ClassDefinition.AppendLine(('# class definition created by {0} at {1} for object type {2}' -f $MyInvocation.MyCommand,(Get-Date),$ObjectType)) | |
[void]$ClassDefinition.AppendLine('') | |
} | |
[void]$ClassDefinition.AppendLine(('class {0} {{' -f $BaseClassName)) | |
[void]$ClassDefinition.AppendLine('') | |
# part 1: add all properties | |
# part 2: create a new stringbuilder for the properties in the constructor so we only have to loop through properties once | |
$ConstructorProperty = [StringBuilder]::new() | |
[void]$ClassDefinition.AppendLine(('{0}# properties' -f $Indent)) | |
foreach ($PascalCaseProperty in $Properties) { | |
# part 2: ensure best guess for string values for PSCustomObject objects | |
$PropertySetter = '$InputObject.{0}' -f $PascalCaseProperties[$PascalCaseProperty].Name | |
if ($PascalCaseProperties[$PascalCaseProperty].TypeNameOfValue -match 'string' -and $ObjectType -eq 'PSCustomObject' ) { | |
$PropertyTypeConversion = Resolve-PropertyType -PropertyValue $PascalCaseProperties[$PascalCaseProperty].Value | |
$PropertyTypeName = $PropertyTypeConversion | Select-Object -First 1 | |
if ('Parse' -in $PropertyTypeConversion) { | |
$PropertySetter = '[datetime]::Parse($InputObject.{0},(Get-Culture))' -f $PascalCaseProperties[$PascalCaseProperty].Name | |
} elseif ('ParseExact' -in $PropertyTypeConversion) { | |
$PropertySetter = '[datetime]::ParseExact($InputObject.{0},''{1}'',(Get-Culture))' -f $PascalCaseProperties[$PascalCaseProperty].Name,$PropertyTypeConversion[2] | |
} | |
} else { | |
if ($PascalCaseProperties[$PascalCaseProperty].TypeNameOfValue -match 'PSCustomObject') { | |
#$PropertyTypeName = 'PSCustomObject' | |
$PropertyTypeName = "$BaseClassName$PascalCaseProperty" | |
# part 3: make it recursive | |
$ConvertParams = @{ | |
ClassName = "$BaseClassName$PascalCaseProperty" | |
} | |
if ($PSBoundParameters.ContainsKey('NoComments')) { | |
$ConvertParams.Add('NoComments',$true) | |
} | |
$PascalCaseProperties[$PascalCaseProperty].Value | ConvertTo-ClassDefinition @ConvertParams | |
} else { | |
$PropertyTypeName = $PascalCaseProperties[$PascalCaseProperty].TypeNameOfValue | |
} | |
} | |
# part 2: if a property needs to be hidden, add that to the property statement | |
if ($PascalCaseProperties[$PascalCaseProperty].Name -in $HiddenProperty -or $PascalCaseProperty -in $HiddenProperty) { | |
$PropertyStatement = '{0}hidden [{1}]${2}' -f $Indent,$PropertyTypeName,$PascalCaseProperty | |
} else { | |
$PropertyStatement = '{0}[{1}]${2}' -f $Indent,$PropertyTypeName,$PascalCaseProperty | |
} | |
[void]$ClassDefinition.AppendLine($PropertyStatement) | |
[void]$ConstructorProperty.AppendLine(('{0}{0}$this.{1} = {2}' -f $Indent,$PascalCaseProperty,$PropertySetter)) | |
} | |
[void]$ClassDefinition.AppendLine('') | |
# add simple constructors | |
[void]$ClassDefinition.AppendLine(('{0}# constructors' -f $Indent)) | |
[void]$ClassDefinition.AppendLine(('{0}{1} () {{ }}' -f $Indent,$BaseClassName)) | |
[void]$ClassDefinition.AppendLine(('{0}{1} ([{2}]$InputObject) {{' -f $Indent,$BaseClassName,$ObjectType)) | |
# part 2: ensure proper PascalCase in the constructor | |
[void]$ClassDefinition.AppendLine($ConstructorProperty.ToString().TrimEnd()) | |
[void]$ClassDefinition.AppendLine(('{0}}}' -f $Indent)) | |
# part 3: add methods, ensure proper PascalCase | |
[void]$ClassDefinition.AppendLine('') | |
foreach ($ThisMethod in $Method) { | |
$PascalCaseMethod = ConvertTo-PascalCase -String $ThisMethod | |
[void]$ClassDefinition.AppendLine(('{0}[OutputTypeName] {1} (' -f $Indent,$PascalCaseMethod)) | |
[void]$ClassDefinition.AppendLine(('{0}{0}[TypeName]$Param1,' -f $Indent)) | |
[void]$ClassDefinition.AppendLine(('{0}{0}[TypeName]$Param2' -f $Indent)) | |
[void]$ClassDefinition.AppendLine(('{0}) {{' -f $Indent)) | |
[void]$ClassDefinition.AppendLine(('{0}{0}# your code' -f $Indent)) | |
[void]$ClassDefinition.AppendLine(('{0}{0}return $Output' -f $Indent)) | |
[void]$ClassDefinition.AppendLine(('{0}}}' -f $Indent)) | |
[void]$ClassDefinition.AppendLine('') | |
} | |
# end class | |
[void]$ClassDefinition.AppendLine('}') | |
[void]$ClassDefinition.AppendLine('') | |
# output class definition | |
$ClassDefinition.ToString() | |
} | |
function Resolve-PropertyType { | |
[CmdletBinding()] | |
param( | |
[Parameter(Mandatory,ValueFromPipeline)] | |
[string]$PropertyValue | |
) | |
$TwitterDateFormat ='ddd MMM dd HH:mm:ss zzz yyyy' | |
# check for url | |
try { | |
[void][Uri]::new($PropertyValue) | |
return 'Uri' | |
} | |
catch { } # do nothing, continue to next text | |
# check for known date time | |
try { | |
[void][datetime]::Parse($PropertyValue,(Get-Culture)) | |
return 'DateTime','Parse' | |
} | |
catch { } | |
# check for Twitter date time | |
try { | |
[void][datetime]::ParseExact($PropertyValue,$TwitterDateFormat,(Get-Culture)) | |
return 'DateTime','ParseExact',$TwitterDateFormat | |
} | |
catch { } | |
return 'String' | |
} | |
function ConvertTo-PascalCase { | |
[CmdletBinding()] | |
param( | |
[Parameter(Mandatory,ValueFromPipeline)] | |
[string[]]$String | |
) | |
begin { | |
$Culture = Get-Culture | |
} | |
process { | |
foreach ($Word in $String) { | |
$Words = $Word -split '\W|_' | |
$PascalCase = if ($Words.Count -gt 1) { | |
$Words | ForEach-Object { | |
$Culture.TextInfo.ToTitleCase($_.ToLower()) | |
} | |
} else { | |
if ($Word -cnotmatch '^[A-Z]') { | |
return $Culture.TextInfo.ToTitleCase($Word) | |
} else { | |
return $Word | |
} | |
} | |
} | |
$PascalCase -join '' | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment