Azure CLI Shorthand Syntax (Preview)
======

Azure cli shorthand syntax can help cli users to pass complicated argument values.
 Only the arguments of AAZ(Atomic Azure CLI) commands generated by aaz-dev tool support shorthand syntax.

The command lines written in shorthand syntax can run in both _Powershell_ and _Bash_ terminals without any change in must situations.

[1. Shorthand syntax formats](#shorthand-syntax-formats)

[1.1. `Full Value` format](#full-value-format)

[1.2. `Partial Value` format](#partial-value-format)

[1.3. Combine with `Full Value` and `Partial Value`](#combine-with-full-value-and-partial-value)

[1.4. use `??` to show help](#use--to-show-help)

[1.5. Pass a `null` Value](#pass-a-null-value)

[2. Single Quotes String](#single-quotes-string)

[2.1. Pass a string value with space and other special characters](#pass-a-string-value-with-space-and-other-special-characters)

[2.2. Pass a "null" string value](#pass-a-null-string-value)

[2.3. Use `'/` to Pass `'`](#use--to-pass-)


# Shorthand syntax formats

## `Full Value` format

Shorthand syntax in `Full Value` format is json without __double quotes__.
For example if you want to pass following object in --contact argument:

Json:
```json
{
  "name": "Bill",
  "age": 20,
  "paid": true,
  "emails": [
    "Bill@microsoft.com",
    "Bill@outlook.com"
  ],
  "address": {
    "country": "USA",
    "company": "Microsoft",
    "details": {
      "line1": "15590 NE 31st St",
      "line2": "Redmond, WA"
    }
  }
}
```

Shorthand in both _Powershell_ and _Bash_:
```bash
az some-command --contact "{name:Bill,age:20,paid:true,emails:[Bill@microsoft.com,Bill@outlook.com],address:{country:USA,company:Microsoft,details:{line1:'15590 NE 31st St',line2:'Redmond, WA'}}}"
```

In the example above you can see the shorthand syntax wrapped in double quotes to make sure the value passed as string in both powershell and bash.
Please don't use single quotes to wrap the shorthand syntax, because single quotes are used for _Single Quotes String_ introduced later.


## `Partial Value` format

Shorthand syntax for partial value is composed of two parts joined by `=`: the index key and the value. It's format is `{key}={value}`

The value can be simple string, full value format, json or even json file path.

For the above example, if we want to pass some part properties of --contact:

Use `Partial Value` for _name_ properties:
```bash
az some-command --contact name=Bill
```

Use `Partial Value` for both _age_ and _paid_ properties
```bash
az some-command --contact age=20 paid=true
```

Use `Partial Value` for second element of _emails_
```bash
az some-command --contact emails[1]="Bill@outlook.com"
```

Use `Partial Value` for _details_ property of _address_.
```bash
az some-command --contact address.details="{line1:'15590 NE 31st St',line2:'Redmond, WA'}"
```

It's also possible to pass json file as value.

Use `json file` for value:
```bash
az some-command --contact address.details=./address_detials.json
```

## Combine with `Full Value` and `Partial Value`

You can combine with `Full Value` and `Partial Value` in one argument.
For example if you want to pass following object in --contact argument:

Json:
```json
{
  "name": "Bill",
  "motto": "One man's bug is another man's lesson.",
  "age": 20,
  "paid": true,
  "emails": [
    "Bill@microsoft.com",
    "Bill@outlook.com"
  ]
}
```

The motto property has ` ` character, so in `Full Value` format, it should be a [__Single Quotes String__](#single-quotes-string).
However in __Single Quotes String__, the `'` should be replaced by `'/`. So in `Full Value`, it should be passed like `'One man'/s bug is another man'/s lesson.'`.

Use `Full Value`:
```bash
az some-command --contact "{name:Bill,motto:'One man'/s bug is another man'/s lesson.',age:20,paid:true,emails:[Bill@microsoft.com,Bill@outlook.com]}"
```

However in `Partial Value` format, the motto can be parsed as string, and it doesn't need to be a __Single Quotes String__.

Use `Partial Value`:
```bash
az some-command --contact motto="One man's bug is another man's lesson."
```

Shorthand syntax arguments support to patch `Full Value` by adding `Partial Value` after it.

Use `Full Value` and `Partial Value`:
```bash
az some-command --contact "{name:Bill,age:20,paid:true,emails:[Bill@microsoft.com,Bill@outlook.com]}" motto="One man's bug is another man's lesson."
```

You can also patch a new element of list property in `Full Value`. For example you can set the second email address by `Partial Value`:
```bash
az some-command --contact "{name:Bill,age:20,paid:true,emails:[Bill@microsoft.com]}" emails[1]="Bill@outlook.com" motto="One man's bug is another man's lesson."
```

There's no limitation to put them after one --contact flag or put them after two --contact flags.

Use `Full Value` and `Partial Value` in two --contact flags:
```bash
az some-command --contact "{name:Bill,age:20,paid:true,emails:[Bill@microsoft.com]}" \
--contact emails[1]="Bill@outlook.com" \
--contact motto="One man's bug is another man's lesson."
```

The __order__ of them is important!!! If you reverse the order, the final data will only be the `Full Value` without properties defined in `Partial Value`. 

## use `??` to show help

`??` is a special keyword to show argument or its sub property help message. It can be use in any place of shorthand syntax.


### use `??` to show argument's help message

Show help message of `--contact` argument:
```bash
az some-command --contact ??
```

### use `??` in `Full Value` format

Show help message of `--contant` argument when writing `Full Value`:
```bash
az some-command --contact "{??"
```
```bash
az some-command --contact "{name:Bill,??"
```

Show help message of `--contant.address` property when writing `Full Value`:
```bash
az some-command --contact "{name:Bill,address:??"
```

Show help message of `--contant.address.country` property when writing `Full Value`:
```bash
az some-command --contact "{name:Bill,address:{country:??"
```

Show help message of `--contant.emails` property when writing `Full Value`:
```bash
az some-command --contact "{name:Bill,address:{country:USA},emails:??"
```

Show help message of the element of `--contant.emails` property when writing `Full Value`:
```bash
az some-command --contact "{name:Bill,address:{country:USA},emails:[??"
```

### use `??` in `Partial Value` format

Show help message of `--contant.address` property when writing `Partial Value`:
```bash
az some-command --contact address=??
```

Show help message of `--contant.emails` property when writing `Partial Value`:
```bash
az some-command --contact emails=??
```

Show help message of the element of `--contant.emails` property when writing `Partial Value`:
```bash
az some-command --contact emails[0]=??
```

## Pass a `null` Value

Shorthand syntax support `null` keyword in both `Full Value` and `Partial Value` formats.

For example if you want to pass following object with `null` value address property in --contact argument:

Json:
```json
{
  "name": "Bill",
  "age": 20,
  "paid": true,
  "emails": [
    "Bill@microsoft.com",
    "Bill@outlook.com"
  ],
  "address": null
}
```

pass `null` in `Full Value`:
```bash
az some-command --contact "{name:Bill,age:20,paid:true,emails:[Bill@microsoft.com,Bill@outlook.com],address:null}"
```

pass `null` in `Partial Value`:
```bash
az some-command --contact name=Bill address=null
```

### `null` value in update commands

In update commands `null` value is usually used to unset properties of a object or remove elements of an array or a dict.
For example if there already exists an resource with following contact property

contact
```json
{
  "contact": {
    "name": "Bill",
    "age": 20,
    "paid": true,
    "emails": [
      "Bill@microsoft.com",
      "Bill@outlook.com"
    ],
    "address": {
      "country": "USA",
      "company": "Microsoft",
      "details": {
        "line1": "15590 NE 31st St",
        "line2": "Redmond, WA"
      }
    }
  },

  "other_properties": {}
}
```

By using `null` value in update command, _address_ property of resource's _contact_ can be unset:
```bash
az some-update-command --contact address=null
```

By using `null` value in update command, the first element of resource's _emails_ can be removed:
```bash
az some-update-command --emails [0]=null
```

# Single Quotes String

_Single Quotes String_ is used to pass a __string__ value with special characters: `:`, `,`, `{`, `}`, `[`, `]`, `null`, `??` and space.
Because those characters usually have other meanings when parsing shorthand syntax. So with single quotes, it tells parser to parse as a string only.

## Pass a string value with space and other special characters

For example if you want to pass following object in --contact argument:

Json:
```json
{
  "name": "Bill RP",
  "age": 20,
  "paid": true,
  "data": "{a: [1, 2]}"
}
```

Pass in `Full Value` format:
```bash
az some-command --contact "{name:'Bill RP',age:20,paid:true,data:'{a: [1, 2]}'}"
```

Pass `Partial Value` format:
```bash
az some-command --contact name="'Bill RP'" data="'{a: [1, 2]}'"
```

It's also possible to remove single quotes for name, because it will not distinguish with `Full Value` expression, `null` value or `??` flag.
Pass `Partial Value` format:
```bash
az some-command --contact name="Bill RP"
```

## Pass a "null" string value

Sometime it's required to pass a "null" string value. In order to distinguish with `null` value, it needs to be a _Single Quotes String_.
For example if you want to pass "null" string into name property in --contact argument:

Json:
```json
{
  "name": "null",
  "age": 20,
  "paid": true
}
```

Pass `Full Value` format:
```bash
az some-command --contact "{name:'null',age:20,paid:true}"
```

Pass `Partial Value` format:
```bash
az some-command --contact name="'null'"
```

## Use `'/` to Pass `'`

The character `'` needs special escape in _Single Quotes String_ in order to distinguish with end of _Single Quotes String_. You can use `'/` to pass `'` in _Single Quotes String_.
It should be reminded that `/` is a escape character __only__ after `'` in _Single Quotes String_. If `/` is not in _Single Quotes String_ or `/` is not after `'`, `/` is a normal character.

For example if you want to pass "bill's" string into name property in --contact argument:

Json:
```json
{
  "name": "null",
  "age": 20,
  "paid": true
}
```

Pass `Full Value` format:
```bash
az some-command --contact "{name:'bill'/s',age:20,paid:true}"
```

Pass `Partial Value` format:
```bash
az some-command --contact name="'bill'/s'"
```

If value is not in _Single Quotes String_, you don't need to add escape character after `'`.

Pass `Partial Value` format:
```bash
az some-command --contact name="bill's"
```
