Package client provides a Go SDK for interacting with the Market Data API. It includes functionality for making API requests, handling responses, managing rate limits, and logging. The SDK supports various data types including stocks, options, and market status information. To use the SDK, you first need to create an instance of MarketDataClient using the GetClient function. This client will then be used to make API requests to the Market Data API. The SDK uses an API token for authentication. The token can be set as an environment variable (MARKETDATA_TOKEN) or directly in your code. However, storing tokens in your code is not recommended for security reasons. The MarketDataClient automatically tracks and manages the API's rate limits. You can check if the rate limit has been exceeded with the RateLimitExceeded method. The SDK logs all unsuccessful (400-499 and 500-599) responses to specific log files based on the response status code. Successful responses (200-299) are logged when debug mode is enabled. Logs include detailed information such as request and response headers, response status code, and the response body. Debug mode can be enabled by calling the Debug method on the MarketDataClient instance. When enabled, the SDK will log detailed information about each request and response, which is useful for troubleshooting. Package client provides a Go SDK for interacting with the Market Data API. The Market Data Go Client includes functionality for making API requests, handling responses, managing rate limits, and logging. The SDK supports various data types including stocks, options, indices, and market status information. The MarketDataClient is a singleton client that is used to interact with the Market Data API. If you are using an environment variable to store your token, the client will be intialized automatically when the package is imported. If you are not using an environment variable, you can initialize the client manually using the NewClient method. After you initialize it for the first time, it is not neccessary to reinitialize it again. The client is thread-safe and can be used across multiple goroutines. Do not attempt to create multiple instances of the client. Package client includes types and methods to access the Funds / Candles endpoint. Retrieve historical price candles for any supported stock symbol. Use FundCandlesRequest to make requests to the endpoint using any of the three supported execution methods: Package client includes types and methods to access the Index Candles endpoint. Get historical price candles for any supported stock index. Use IndicesCandlesRequest to make requests to the endpoint using any of the three supported execution methods: Package client includes types and methods to access the Index Quotes endpoint. Retrieve real-time quotes for any supported index. Utilize IndexQuoteRequest to make requests to the endpoint through one of the three supported execution methods: Package client provides a collection of structs for logging. The Market Data Go SDK provides a comprehensive logging framework tailored for HTTP request and response tracking. It facilitates detailed logging of HTTP interactions, including request details, response data, error handling, and rate limit monitoring. The logging functionality is designed to support a wide range of market data types such as stocks, options, indices, and market status information, making it an essential tool for developers integrating market data into their applications. Package client includes types and methods to access the Market Status endpoint. Retrieve current, future, and historical open / closed status information. Utilize MarketStatusRequest to make requests to the endpoint through one of the three supported execution methods: Package client provides functionalities to interact with the Options Chain endpoint. Retrieve a a complete or filtered options chain for a given underlying symbol. Both real-time and historical requests are possible. Utilize OptionChainRequest for querying the endpoint through one of the three available methods: Package client provides functionalities to interact with the Options Expirations endpoint. Get a list of current or historical option expiration dates for an underlying symbol. Utilize OptionsExpirationsRequest for querying the endpoint through one of the three available methods: Package client provides functionalities to interact with the Options Lookup endpoint. Lookup the official option symbol based on a user's text input. Utilize [OptionsLookupRequest] for querying the endpoint through one of the three available methods: Package client provides functionalities to interact with the Options Quotes endpoint. Retrieve an option quote for a given option symbol. Utilize OptionQuoteRequest for querying the endpoint through one of the three available methods: Package client provides functionalities to interact with the Option Strikes endpoint. Retrieve a complete or filtered list of option strike prices for a given underlying symbol. Both real-time and historical requests are possible. Utilize OptionStrikesRequest for querying the endpoint through one of the three available methods: Package client provides functionalities to interact with the Bulk Stock Candles endpoint. Get bulk historical price data for many stock symbols at once or even obtain a full market snapshot. Utilize the BulkStockCandlesRequest for querying the endpoint through one of the three available methods: Package client includes types and methods to access the Bulk Stock Quotes endpoint. Retrieve live quotes for multiple stocks symbols in a single request or even get a full market snapshot with a quote for all symbols. Utilize BulkStockQuotesRequest to make requests to the endpoint through one of the three supported execution methods: Package client includes types and methods to access the Stock Candles endpoint. Retrieve historical price candles for any supported stock symbol. Use StockCandlesRequest to make requests to the endpoint using any of the three supported execution methods: Package client includes types and methods to access the Stock Earnings endpoint. Retrieve earnings data for any supported stock symbol. Use StockEarningsRequest to make requests to the endpoint using any of the three supported execution methods: Package client includes types and methods to access the Stock News endpoint. Retrieve news articles for any supported stock symbol. Use StockNewsRequest to make requests to the endpoint using any of the three supported execution methods: Package client includes types and methods to access the Stock Quotes endpoint. Retrieve live quotes for any supported stock symbol. Utilize StockQuoteRequest to make requests to the endpoint through one of the three supported execution methods: Package stocks provides the /stocks endpoints
Package enmime implements a MIME encoding and decoding library. It's built on top of Go's included mime/multipart support where possible, but is geared towards parsing MIME encoded emails. The enmime API has two conceptual layers. The lower layer is a tree of Part structs, representing each component of a decoded MIME message. The upper layer, called an Envelope provides an intuitive way to interact with a MIME message. Calling ReadParts causes enmime to parse the body of a MIME message into a tree of Part objects, each of which is aware of its content type, filename and headers. The content of a Part is available as a slice of bytes via the Content field. If the part was encoded in quoted-printable or base64, it is decoded prior to being placed in Content. If the Part contains text in a character set other than utf-8, enmime will attempt to convert it to utf-8. To locate a particular Part, pass a custom PartMatcher function into the BreadthMatchFirst() or DepthMatchFirst() methods to search the Part tree. BreadthMatchAll() and DepthMatchAll() will collect all Parts matching your criteria. ReadEnvelope returns an Envelope struct. Behind the scenes a Part tree is constructed, and then sorted into the correct fields of the Envelope. The Envelope contains both the plain text and HTML portions of the email. If there was no plain text Part available, the HTML Part will be down-converted using the html2text library1. The root of the Part tree, as well as slices of the inline and attachment Parts are also available. Every MIME Part has its own headers, accessible via the Part.Header field. The raw headers for an Envelope are available in Root.Header. Envelope also provides helper methods to fetch headers: GetHeader(key) will return the RFC 2047 decoded value of the specified header. AddressList(key) will convert the specified address header into a slice of net/mail.Address values. enmime attempts to be tolerant of poorly encoded MIME messages. In situations where parsing is not possible, the ReadEnvelope and ReadParts functions will return a hard error. If enmime is able to continue parsing the message, it will add an entry to the Errors slice on the relevant Part. After parsing is complete, all Part errors will be appended to the Envelope Errors slice. The Error* constants can be used to identify a specific class of error. Please note that enmime parses messages into memory, so it is not likely to perform well with multi-gigabyte attachments. enmime is open source software released under the MIT License. The latest version can be found at https://github.com/jhillyerd/enmime
Package pot (Pieces of Text) provides a lightweight text serialization parser that is intended to be used together with Go's encoding.TextUnmarshaler interface. There is only de-serialization support, it's easy enough to generate properly formated POT directly from a encoding.Textmarshaler. The POT format is similar to JSON but with some differences required by the application that POT was created for. There are two compound types, a dictionary and a list and two string types. The dictionary type may hold duplicate keys and the key order is maintained. This makes it more of an itemized list than a dictionary type. The list type simply holds a sequence of other types. There are no numeric or boolean types, all parsing eventually produces strings. It's up to an applications TextUnmarshaler functions to parse these strings. Strings are separated by space, strings may contain space if quoted or escaped. The characters that may be used for keys in dictionaries are artificially limited similar to variable names in most programming languages. The characters a-z, A-Z, 0-9 are allowed in any position, the character '-' is allowed in any position but the first. Dictionary keys are delimited by values by ':'. Dictionaries: Lists: Strings: The escape character is '\'. Characters '{', '}', '[', ']', ':', ' ' must be quoted or escaped in strings. Characters '\' and '"' must be escaped in strings. Additionally '\n' produces a new-line, '\r' a carriage return and '\t' a tab. Create a new root level parser and call parser.Next() until it returns nil or an error. There is also ParserScanner type that wraps a parser interface to provide a bufio.Scanner like API Example:
Package enmime implements a MIME parsing library for Go. It's built on top of Go's included mime/multipart support, but is geared towards parsing MIME encoded emails. The enmime API has two conceptual layers. The lower layer is a tree of Part structs, representing each component of a decoded MIME message. The upper layer, called an Envelope provides an intuitive way to interact with a MIME message. Calling ReadParts causes enmime to parse the body of a MIME message into a tree of Part objects, each of which is aware of its content type, filename and headers. Each Part implements io.Reader, providing access to the content it represents. If the part was encoded in quoted-printable or base64, it is decoded prior to being accessed by the Reader. If you need to locate a particular Part, you can pass a custom PartMatcher function into the BreadthMatchFirst() or DepthMatchFirst() methods to search the Part tree. BreadthMatchAll() and DepthMatchAll() will collect all Parts matching your criteria. EnvelopeFromMessage returns an Envelope struct. Behind the scenes a Part tree is constructed, and then sorted into the correct fields of the Envelope. The Envelope contains both the plain text and HTML portions of the email. If there was no plain text Part available, the HTML Part will be downconverted using the html2text library1. The root of the Part tree, as well as slices of the inline and attachment Parts are also available. Please note that enmime parses messages into memory, so it is not likely to perform well with multi-gigabyte attachments. enmime is open source software released under the MIT License. The latest version can be found at https://github.com/jhillyerd/enmime
Package errors provides detailed stack-traced description for error type and exception(handle-check) style handling This package has two goals. 1. Provide convenient error type which has error code to easily distinguish errors, which can be extended by additional messages(annotations here) while error flows through the program, can be printed with stack trace. 2. Provide convenient way to handle errors in exception style. With the first point everything is clear, let's talk a little about second. Go's error handling idiom usually looks like It is very "holy war" question which way to handle errors, exception like or "returning err" like, is better. Everyone chooses himself which way is more appropriate to him. But doubtlessly "returning err" style has some disadvantages. 1. Error handling logic is mixed with "business" logic so it shadows it 2. Code repetitions, which can cause a bug 3. Verbosity That's why Go 2 draft https://go.googlesource.com/proposal/+/master/design/go2draft.md contains new Handle-Check error handling approach, which is quite similar to exception approach. This package provides similar to this Handle-Check mechanism, based on panics. Details are below =) All errors created by this package are returned as golang native error interface. Underlying type is immutable, so one can't change smth in already existing error, but can use wrap functions, which create new one based on underlying. New, Errorf, Codef - creates new error. Wrap, WrapAnnotated - wrap existing. Error can be created with error code, which has interface{} type. Error code can be obtained from error by ErrCode function. Missing error code in creation is equal to nil error code. When one wraps error without providing error code, it is preserved. Otherwise - overridden. With WrapAnnotated one can add additional messages to an error. Annotations are printed in stacktrace, bound to corresponding function(where it was added). If annotation was added out of functions in stacktrace, it will be printed in separate section. %v modifier will print full info, with stack trace and annotations. %s only error message. %q only error message quoted. E.g. with %v: To get underlying error use Cause func. All creation & wrapping functions have their duplicates with _skipstack suffix and skip argument. With those functions one can specify correct first stack frame to print in stack trace. skip==0 means starting from caller of this function. It can be useful for example to skip stack frames of wrapper object, if you want your own wrapper of this package. example: This is comprehensive, pretending to be close to real-life example of using this package. It's easier to see it in code, but if you use godoc, please, notice https://godoc.org/github.com/pashaosipyants/errors/example_auxiliary package, which is used here. Imagine there is an api to create a task that executes another service. Besides user of this api wants to hold info whether this task is already done. This api, ofc, can return error. E.g. certain task may be already created. If so, error should report whether it is done or not.
Package money implements immutable amounts and exchange rates. Currency is represented as an integer index into an in-memory array that stores properties defined by ISO 4217: The currently supported currencies use scales of 0, 2, or 3: Amount is a struct with two fields: ExchangeRate is a struct with three fields: The range of an amount is determined by the scale of its currency. Similarly, the range of an exchange rate is determined by the scale of its quote currency. Here are the ranges for scales 0, 2, and 3: Subnormal numbers are not supported by the underlying decimal.Decimal type. Consequently, amounts and exchange rates between -0.00000000000000000005 and 0.00000000000000000005 inclusive are rounded to 0. The package provides methods for converting: See the documentation for each method for more details. Each arithmetic operation is carried out in two steps: The operation is initially performed using uint64 arithmetic. If no overflow occurs, the exact result is immediately returned. If an overflow does occur, the operation proceeds to step 2. The operation is repeated with increased precision using big.Int arithmetic. The result is then rounded to 19 digits. If no significant digits are lost during rounding, the inexact result is returned. If any significant digit is lost, an overflow error is returned. Step 1 was introduced to improve performance by avoiding heap allocation for big.Int and the complexities associated with big.Int arithmetic. It is expected that, in transactional financial systems, the majority of arithmetic operations will successfully compute an exact result during step 1. The following rules are used to determine the significance of digits during step 2: Amount.Add, Amount.Sub, Amount.SubAbs, Amount.Mul, Amount.FMA, Amount.Quo, Amount.QuoRem, ExchangeRate.Conv, ExchangeRate.Mul, ExchangeRate.Inv: All digits in the integer part are significant. In the fractional part, digits are significant up to the scale of the currency. Amount.Rat: All digits in the integer part are significant, while digits in the fractional part are considered insignificant. Implicit rounding is applied when a result exceeds 19 digits. In such cases, the result is rounded to 19 digits using half-to-even rounding. This method ensures that rounding errors are evenly distributed between rounding up and rounding down. For all arithmetic operations, the result is the one that would be obtained by computing the exact mathematical result with infinite precision and then rounding it to 19 digits. In addition to implicit rounding, the package provides several methods for explicit rounding: See the documentation for each method for more details. All methods are panic-free and pure. Errors are returned in the following cases: Currency Mismatch. All arithmetic operations, except for Amount.Rat, return an error if the operands are denominated in different currencies. Division by Zero. Unlike the standard library, Amount.Quo, Amount.QuoRem, Amount.Rat, and ExchangeRate.Inv do not panic when dividing by 0. Instead, they return an error. Overflow. Unlike standard integers, there is no "wrap around" for amounts at certain sizes. Arithmetic operations return an error for out-of-range values. Underflow. All arithmetic operations, except for ExchangeRate.Inv and ExchangeRate.Mul, do not return an error in case of underflow. If the result is an amount between -0.00000000000000000005 and 0.00000000000000000005 inclusive, it is rounded to 0. ExchangeRate.Inv and ExchangeRate.Mul return an error in cases of underflow, as the result of these operations is an exchange rate, and exchange rates cannot be 0. This example calculates the effective interest rate for a 10% nominal interest rate compounded monthly on a USD 10,000 balance. In this example, a loan amortization table is generated for a loan with an initial amount of USD 12,000, an annual interest rate of 10%, and a repayment period of 1 year. In this example, we parse the string "840D000000001234", which represents -12.34 USD, according to the specification for "DE54, Additional Amounts" in ISO 8583. This is an example of how to a parse a monetary amount formatted as money.proto. This is an example of how to a parse a monetary amount formatted according to Stripe API specification. In this example, the sales tax amount is calculated for a product with a given price after tax, using a specified tax rate.
Package enmime implements a MIME encoding and decoding library. It's built on top of Go's included mime/multipart support where possible, but is geared towards parsing MIME encoded emails. The enmime API has two conceptual layers. The lower layer is a tree of Part structs, representing each component of a decoded MIME message. The upper layer, called an Envelope provides an intuitive way to interact with a MIME message. Calling ReadParts causes enmime to parse the body of a MIME message into a tree of Part objects, each of which is aware of its content type, filename and headers. The content of a Part is available as a slice of bytes via the Content field. If the part was encoded in quoted-printable or base64, it is decoded prior to being placed in Content. If the Part contains text in a character set other than utf-8, enmime will attempt to convert it to utf-8. To locate a particular Part, pass a custom PartMatcher function into the BreadthMatchFirst() or DepthMatchFirst() methods to search the Part tree. BreadthMatchAll() and DepthMatchAll() will collect all Parts matching your criteria. ReadEnvelope returns an Envelope struct. Behind the scenes a Part tree is constructed, and then sorted into the correct fields of the Envelope. The Envelope contains both the plain text and HTML portions of the email. If there was no plain text Part available, the HTML Part will be down-converted using the html2text library1. The root of the Part tree, as well as slices of the inline and attachment Parts are also available. Every MIME Part has its own headers, accessible via the Part.Header field. The raw headers for an Envelope are available in Root.Header. Envelope also provides helper methods to fetch headers: GetHeader(key) will return the RFC 2047 decoded value of the specified header. AddressList(key) will convert the specified address header into a slice of net/mail.Address values. enmime attempts to be tolerant of poorly encoded MIME messages. In situations where parsing is not possible, the ReadEnvelope and ReadParts functions will return a hard error. If enmime is able to continue parsing the message, it will add an entry to the Errors slice on the relevant Part. After parsing is complete, all Part errors will be appended to the Envelope Errors slice. The Error* constants can be used to identify a specific class of error. Please note that enmime parses messages into memory, so it is not likely to perform well with multi-gigabyte attachments. enmime is open source software released under the MIT License. The latest version can be found at https://github.com/jhillyerd/enmime
Package enmime implements a MIME encoding and decoding library. It's built on top of Go's included mime/multipart support where possible, but is geared towards parsing MIME encoded emails. The enmime API has two conceptual layers. The lower layer is a tree of Part structs, representing each component of a decoded MIME message. The upper layer, called an Envelope provides an intuitive way to interact with a MIME message. Calling ReadParts causes enmime to parse the body of a MIME message into a tree of Part objects, each of which is aware of its content type, filename and headers. The content of a Part is available as a slice of bytes via the Content field. If the part was encoded in quoted-printable or base64, it is decoded prior to being placed in Content. If the Part contains text in a character set other than utf-8, enmime will attempt to convert it to utf-8. To locate a particular Part, pass a custom PartMatcher function into the BreadthMatchFirst() or DepthMatchFirst() methods to search the Part tree. BreadthMatchAll() and DepthMatchAll() will collect all Parts matching your criteria. ReadEnvelope returns an Envelope struct. Behind the scenes a Part tree is constructed, and then sorted into the correct fields of the Envelope. The Envelope contains both the plain text and HTML portions of the email. If there was no plain text Part available, the HTML Part will be down-converted using the html2text library1. The root of the Part tree, as well as slices of the inline and attachment Parts are also available. Every MIME Part has its own headers, accessible via the Part.Header field. The raw headers for an Envelope are available in Root.Header. Envelope also provides helper methods to fetch headers: GetHeader(key) will return the RFC 2047 decoded value of the specified header. AddressList(key) will convert the specified address header into a slice of net/mail.Address values. enmime attempts to be tolerant of poorly encoded MIME messages. In situations where parsing is not possible, the ReadEnvelope and ReadParts functions will return a hard error. If enmime is able to continue parsing the message, it will add an entry to the Errors slice on the relevant Part. After parsing is complete, all Part errors will be appended to the Envelope Errors slice. The Error* constants can be used to identify a specific class of error. Please note that enmime parses messages into memory, so it is not likely to perform well with multi-gigabyte attachments. enmime is open source software released under the MIT License. The latest version can be found at https://github.com/mtringuyen/enmime
Package ward provides tooling to connect to the Ward Trucking API. This is for truck shipments, not small parcels. Think LTL (less than truckload) shipments. This code was created off the Ward API documentation. This uses and XML SOAP API. You will need to have a Ward account and register for access to use this. Currently this package can perform: - pickup requests - rate quotes To create a pickup request: - Set test or production mode (SetProductionMode()). - Set shipper information (ShipperInfomation{}). - Set shipment data (PickupRequestShipment{}). - Create the pickup request object (PickupRequest{}). - Request the pickup (RequestPickup()). - Check for any errors. To get a rate quote: - Create the item you want a quote on (RateQuoteDetailItem{}). - Create the inner request with details (RateQuoteRequestInner{}). - Create the rate quote request (RateQuoteRequest{}). - Request the rate quote (RateQuote()). - Check for any errors.
Package enmime implements a MIME encoding and decoding library. It's built on top of Go's included mime/multipart support where possible, but is geared towards parsing MIME encoded emails. The enmime API has two conceptual layers. The lower layer is a tree of Part structs, representing each component of a decoded MIME message. The upper layer, called an Envelope provides an intuitive way to interact with a MIME message. Calling ReadParts causes enmime to parse the body of a MIME message into a tree of Part objects, each of which is aware of its content type, filename and headers. The content of a Part is available as a slice of bytes via the Content field. If the part was encoded in quoted-printable or base64, it is decoded prior to being placed in Content. If the Part contains text in a character set other than utf-8, enmime will attempt to convert it to utf-8. To locate a particular Part, pass a custom PartMatcher function into the BreadthMatchFirst() or DepthMatchFirst() methods to search the Part tree. BreadthMatchAll() and DepthMatchAll() will collect all Parts matching your criteria. ReadEnvelope returns an Envelope struct. Behind the scenes a Part tree is constructed, and then sorted into the correct fields of the Envelope. The Envelope contains both the plain text and HTML portions of the email. If there was no plain text Part available, the HTML Part will be down-converted using the html2text library1. The root of the Part tree, as well as slices of the inline and attachment Parts are also available. Every MIME Part has its own headers, accessible via the Part.Header field. The raw headers for an Envelope are available in Root.Header. Envelope also provides helper methods to fetch headers: GetHeader(key) will return the RFC 2047 decoded value of the specified header. AddressList(key) will convert the specified address header into a slice of net/mail.Address values. enmime attempts to be tolerant of poorly encoded MIME messages. In situations where parsing is not possible, the ReadEnvelope and ReadParts functions will return a hard error. If enmime is able to continue parsing the message, it will add an entry to the Errors slice on the relevant Part. After parsing is complete, all Part errors will be appended to the Envelope Errors slice. The Error* constants can be used to identify a specific class of error. Please note that enmime parses messages into memory, so it is not likely to perform well with multi-gigabyte attachments. enmime is open source software released under the MIT License. The latest version can be found at https://github.com/sschekotikhin/enmime
Package enmime implements a MIME encoding and decoding library. It's built on top of Go's included mime/multipart support where possible, but is geared towards parsing MIME encoded emails. The enmime API has two conceptual layers. The lower layer is a tree of Part structs, representing each component of a decoded MIME message. The upper layer, called an Envelope provides an intuitive way to interact with a MIME message. Calling ReadParts causes enmime to parse the body of a MIME message into a tree of Part objects, each of which is aware of its content type, filename and headers. The content of a Part is available as a slice of bytes via the Content field. If the part was encoded in quoted-printable or base64, it is decoded prior to being placed in Content. If the Part contains text in a character set other than utf-8, enmime will attempt to convert it to utf-8. To locate a particular Part, pass a custom PartMatcher function into the BreadthMatchFirst() or DepthMatchFirst() methods to search the Part tree. BreadthMatchAll() and DepthMatchAll() will collect all Parts matching your criteria. ReadEnvelope returns an Envelope struct. Behind the scenes a Part tree is constructed, and then sorted into the correct fields of the Envelope. The Envelope contains both the plain text and HTML portions of the email. If there was no plain text Part available, the HTML Part will be down-converted using the html2text library1. The root of the Part tree, as well as slices of the inline and attachment Parts are also available. Every MIME Part has its own headers, accessible via the Part.Header field. The raw headers for an Envelope are available in Root.Header. Envelope also provides helper methods to fetch headers: GetHeader(key) will return the RFC 2047 decoded value of the specified header. AddressList(key) will convert the specified address header into a slice of net/mail.Address values. enmime attempts to be tolerant of poorly encoded MIME messages. In situations where parsing is not possible, the ReadEnvelope and ReadParts functions will return a hard error. If enmime is able to continue parsing the message, it will add an entry to the Errors slice on the relevant Part. After parsing is complete, all Part errors will be appended to the Envelope Errors slice. The Error* constants can be used to identify a specific class of error. Please note that enmime parses messages into memory, so it is not likely to perform well with multi-gigabyte attachments. enmime is open source software released under the MIT License. The latest version can be found at https://github.com/jhillyerd/enmime
Command pigeon generates parsers in Go from a PEG grammar. From Wikipedia [0]: Its features and syntax are inspired by the PEG.js project [1], while the implementation is loosely based on [2]. Formal presentation of the PEG theory by Bryan Ford is also an important reference [3]. An introductory blog post can be found at [4]. The pigeon tool must be called with PEG input as defined by the accepted PEG syntax below. The grammar may be provided by a file or read from stdin. The generated parser is written to stdout by default. The following options can be specified: The tool makes no attempt to format the code, nor to detect the required imports. It is recommended to use goimports to properly generate the output code: The goimports tool can be installed with: If the code blocks in the grammar (see below, section "Code block") are golint- and go vet-compliant, then the resulting generated code will also be golint- and go vet-compliant. The generated code doesn't use any third-party dependency unless code blocks in the grammar require such a dependency. The accepted syntax for the grammar is formally defined in the grammar/pigeon.peg file, using the PEG syntax. What follows is an informal description of this syntax. Identifiers, whitespace, comments and literals follow the same notation as the Go language, as defined in the language specification (http://golang.org/ref/spec#Source_code_representation): The grammar must be Unicode text encoded in UTF-8. New lines are identified by the \n character (U+000A). Space (U+0020), horizontal tabs (U+0009) and carriage returns (U+000D) are considered whitespace and are ignored except to separate tokens. A PEG grammar consists of a set of rules. A rule is an identifier followed by a rule definition operator and an expression. An optional display name - a string literal used in error messages instead of the rule identifier - can be specified after the rule identifier. E.g.: The rule definition operator can be any one of those: A rule is defined by an expression. The following sections describe the various expression types. Expressions can be grouped by using parentheses, and a rule can be referenced by its identifier in place of an expression. The choice expression is a list of expressions that will be tested in the order they are defined. The first one that matches will be used. Expressions are separated by the forward slash character "/". E.g.: Because the first match is used, it is important to think about the order of expressions. For example, in this rule, "<=" would never be used because the "<" expression comes first: The sequence expression is a list of expressions that must all match in that same order for the sequence expression to be considered a match. Expressions are separated by whitespace. E.g.: A labeled expression consists of an identifier followed by a colon ":" and an expression. A labeled expression introduces a variable named with the label that can be referenced in the code blocks in the same scope. The variable will have the value of the expression that follows the colon. E.g.: The variable is typed as an empty interface, and the underlying type depends on the following: For terminals (character and string literals, character classes and the any matcher), the value is []byte. E.g.: For predicates (& and !), the value is always nil. E.g.: For a sequence, the value is a slice of empty interfaces, one for each expression value in the sequence. The underlying types of each value in the slice follow the same rules described here, recursively. E.g.: For a repetition (+ and *), the value is a slice of empty interfaces, one for each repetition. The underlying types of each value in the slice follow the same rules described here, recursively. E.g.: For a choice expression, the value is that of the matching choice. E.g.: For the optional expression (?), the value is nil or the value of the expression. E.g.: Of course, the type of the value can be anything once an action code block is used. E.g.: An expression prefixed with the ampersand "&" is the "and" predicate expression: it is considered a match if the following expression is a match, but it does not consume any input. An expression prefixed with the exclamation point "!" is the "not" predicate expression: it is considered a match if the following expression is not a match, but it does not consume any input. E.g.: The expression following the & and ! operators can be a code block. In that case, the code block must return a bool and an error. The operator's semantic is the same, & is a match if the code block returns true, ! is a match if the code block returns false. The code block has access to any labeled value defined in its scope. E.g.: An expression followed by "*", "?" or "+" is a match if the expression occurs zero or more times ("*"), zero or one time "?" or one or more times ("+") respectively. The match is greedy, it will match as many times as possible. E.g. A literal matcher tries to match the input against a single character or a string literal. The literal may be a single-quoted single character, a double-quoted string or a backtick-quoted raw string. The same rules as in Go apply regarding the allowed characters and escapes. The literal may be followed by a lowercase "i" (outside the ending quote) to indicate that the match is case-insensitive. E.g.: A character class matcher tries to match the input against a class of characters inside square brackets "[...]". Inside the brackets, characters represent themselves and the same escapes as in string literals are available, except that the single- and double-quote escape is not valid, instead the closing square bracket "]" must be escaped to be used. Character ranges can be specified using the "[a-z]" notation. Unicode classes can be specified using the "[\pL]" notation, where L is a single-letter Unicode class of characters, or using the "[\p{Class}]" notation where Class is a valid Unicode class (e.g. "Latin"). As for string literals, a lowercase "i" may follow the matcher (outside the ending square bracket) to indicate that the match is case-insensitive. A "^" as first character inside the square brackets indicates that the match is inverted (it is a match if the input does not match the character class matcher). E.g.: The any matcher is represented by the dot ".". It matches any character except the end of file, thus the "!." expression is used to indicate "match the end of file". E.g.: Code blocks can be added to generate custom Go code. There are three kinds of code blocks: the initializer, the action and the predicate. All code blocks appear inside curly braces "{...}". The initializer must appear first in the grammar, before any rule. It is copied as-is (minus the wrapping curly braces) at the top of the generated parser. It may contain function declarations, types, variables, etc. just like any Go file. Every symbol declared here will be available to all other code blocks. Although the initializer is optional in a valid grammar, it is usually required to generate a valid Go source code file (for the package clause). E.g.: Action code blocks are code blocks declared after an expression in a rule. Those code blocks are turned into a method on the "*current" type in the generated source code. The method receives any labeled expression's value as argument (as interface{}) and must return two values, the first being the value of the expression (an interface{}), and the second an error. If a non-nil error is returned, it is added to the list of errors that the parser will return. E.g.: Predicate code blocks are code blocks declared immediately after the and "&" or the not "!" operators. Like action code blocks, predicate code blocks are turned into a method on the "*current" type in the generated source code. The method receives any labeled expression's value as argument (as interface{}) and must return two values, the first being a bool and the second an error. If a non-nil error is returned, it is added to the list of errors that the parser will return. E.g.: The current type is a struct that provides two useful fields that can be accessed in action and predicate code blocks: "pos" and "text". The "pos" field indicates the current position of the parser in the source input. It is itself a struct with three fields: "line", "col" and "offset". Line is a 1-based line number, col is a 1-based column number that counts runes from the start of the line, and offset is a 0-based byte offset. The "text" field is the slice of bytes of the current match. It is empty in a predicate code block. The parser generated by pigeon exports a few symbols so that it can be used as a package with public functions to parse input text. The exported API is: See the godoc page of the generated parser for the test/predicates grammar for an example documentation page of the exported API: http://godoc.org/github.com/mna/pigeon/test/predicates. Like the grammar used to generate the parser, the input text must be UTF-8-encoded Unicode. The start rule of the parser is the first rule in the PEG grammar used to generate the parser. A call to any of the Parse* functions returns the value generated by executing the grammar on the provided input text, and an optional error. Typically, the grammar should generate some kind of abstract syntax tree (AST), but for simple grammars it may evaluate the result immediately, such as in the examples/calculator example. There are no constraints imposed on the author of the grammar, it can return whatever is needed. When the parser returns a non-nil error, the error is always of type errList, which is defined as a slice of errors ([]error). Each error in the list is of type *parserError. This is a struct that has an "Inner" field that can be used to access the original error. So if a code block returns some well-known error like: The original error can be accessed this way: By defaut the parser will continue after an error is returned and will cumulate all errors found during parsing. If the grammar reaches a point where it shouldn't continue, a panic statement can be used to terminate parsing. The panic will be caught at the top-level of the Parse* call and will be converted into a *parserError like any error, and an errList will still be returned to the caller. The divide by zero error in the examples/calculator grammar leverages this feature (no special code is needed to handle division by zero, if it happens, the runtime panics and it is recovered and returned as a parsing error). Providing good error reporting in a parser is not a trivial task. Part of it is provided by the pigeon tool, by offering features such as filename, position and rule name in the error message, but an important part of good error reporting needs to be done by the grammar author. For example, many programming languages use double-quotes for string literals. Usually, if the opening quote is found, the closing quote is expected, and if none is found, there won't be any other rule that will match, there's no need to backtrack and try other choices, an error should be added to the list and the match should be consumed. In order to do this, the grammar can look something like this: This is just one example, but it illustrates the idea that error reporting needs to be thought out when designing the grammar. Generated parsers have user-provided code mixed with pigeon code in the same package, so there is no package boundary in the resulting code to prevent access to unexported symbols. What is meant to be implementation details in pigeon is also available to user code - which doesn't mean it should be used. For this reason, it is important to precisely define what is intended to be the supported API of pigeon, the parts that will be stable in future versions. The "stability" of the API attempts to make a similar guarantee as the Go 1 compatibility [5]. The following lists what part of the current pigeon code falls under that guarantee (features may be added in the future): The pigeon command-line flags and arguments: those will not be removed and will maintain the same semantics. The explicitly exported API generated by pigeon. See [6] for the documentation of this API on a generated parser. The PEG syntax, as documented above. The code blocks (except the initializer) will always be generated as methods on the *current type, and this type is guaranteed to have the fields pos (type position) and text (type []byte). There are no guarantees on other fields and methods of this type. The position type will always have the fields line, col and offset, all defined as int. There are no guarantees on other fields and methods of this type. The type of the error value returned by the Parse* functions, when not nil, will always be errList defined as a []error. There are no guarantees on methods of this type, other than the fact it implements the error interface. Individual errors in the errList will always be of type *parserError, and this type is guaranteed to have an Inner field that contains the original error value. There are no guarantees on other fields and methods of this type. References:
Package enmime implements a MIME encoding and decoding library. It's built on top of Go's included mime/multipart support where possible, but is geared towards parsing MIME encoded emails. The enmime API has two conceptual layers. The lower layer is a tree of Part structs, representing each component of a decoded MIME message. The upper layer, called an Envelope provides an intuitive way to interact with a MIME message. Calling ReadParts causes enmime to parse the body of a MIME message into a tree of Part objects, each of which is aware of its content type, filename and headers. The content of a Part is available as a slice of bytes via the Content field. If the part was encoded in quoted-printable or base64, it is decoded prior to being placed in Content. If the Part contains text in a character set other than utf-8, enmime will attempt to convert it to utf-8. To locate a particular Part, pass a custom PartMatcher function into the BreadthMatchFirst() or DepthMatchFirst() methods to search the Part tree. BreadthMatchAll() and DepthMatchAll() will collect all Parts matching your criteria. ReadEnvelope returns an Envelope struct. Behind the scenes a Part tree is constructed, and then sorted into the correct fields of the Envelope. The Envelope contains both the plain text and HTML portions of the email. If there was no plain text Part available, the HTML Part will be down-converted using the html2text library1. The root of the Part tree, as well as slices of the inline and attachment Parts are also available. Every MIME Part has its own headers, accessible via the Part.Header field. The raw headers for an Envelope are available in Root.Header. Envelope also provides helper methods to fetch headers: GetHeader(key) will return the RFC 2047 decoded value of the specified header. AddressList(key) will convert the specified address header into a slice of net/mail.Address values. enmime attempts to be tolerant of poorly encoded MIME messages. In situations where parsing is not possible, the ReadEnvelope and ReadParts functions will return a hard error. If enmime is able to continue parsing the message, it will add an entry to the Errors slice on the relevant Part. After parsing is complete, all Part errors will be appended to the Envelope Errors slice. The Error* constants can be used to identify a specific class of error. Please note that enmime parses messages into memory, so it is not likely to perform well with multi-gigabyte attachments. enmime is open source software released under the MIT License. The latest version can be found at https://github.com/jhillyerd/enmime
Package enmime implements a MIME encoding and decoding library. It's built on top of Go's included mime/multipart support where possible, but is geared towards parsing MIME encoded emails. The enmime API has two conceptual layers. The lower layer is a tree of Part structs, representing each component of a decoded MIME message. The upper layer, called an Envelope provides an intuitive way to interact with a MIME message. Calling ReadParts causes enmime to parse the body of a MIME message into a tree of Part objects, each of which is aware of its content type, filename and headers. The content of a Part is available as a slice of bytes via the Content field. If the part was encoded in quoted-printable or base64, it is decoded prior to being placed in Content. If the Part contains text in a character set other than utf-8, enmime will attempt to convert it to utf-8. To locate a particular Part, pass a custom PartMatcher function into the BreadthMatchFirst() or DepthMatchFirst() methods to search the Part tree. BreadthMatchAll() and DepthMatchAll() will collect all Parts matching your criteria. ReadEnvelope returns an Envelope struct. Behind the scenes a Part tree is constructed, and then sorted into the correct fields of the Envelope. The Envelope contains both the plain text and HTML portions of the email. If there was no plain text Part available, the HTML Part will be down-converted using the html2text library1. The root of the Part tree, as well as slices of the inline and attachment Parts are also available. Every MIME Part has its own headers, accessible via the Part.Header field. The raw headers for an Envelope are available in Root.Header. Envelope also provides helper methods to fetch headers: GetHeader(key) will return the RFC 2047 decoded value of the specified header. AddressList(key) will convert the specified address header into a slice of net/mail.Address values. enmime attempts to be tolerant of poorly encoded MIME messages. In situations where parsing is not possible, the ReadEnvelope and ReadParts functions will return a hard error. If enmime is able to continue parsing the message, it will add an entry to the Errors slice on the relevant Part. After parsing is complete, all Part errors will be appended to the Envelope Errors slice. The Error* constants can be used to identify a specific class of error. Please note that enmime parses messages into memory, so it is not likely to perform well with multi-gigabyte attachments. enmime is open source software released under the MIT License. The latest version can be found at https://github.com/jhillyerd/enmime