/**
 * An interface which represents an object which needs
 * to be disposed when it is no longer in use.
 */
export interface IDisposable {
  dispose: () => void
}

/**
 * Dispose all of the items in an array of disposables
 * @param disposables The array of disposable objects
 */
export function dispose<T extends IDisposable> (disposables: T[]): T[] {
  disposables.forEach(d => d.dispose());
  return [];
}

/**
 * Convert a dispose function into an IDisposable object
 * @param dispose The dipose function
 */
export function toDisposable (dispose: () => void): IDisposable {
  return { dispose };
}

/**
 * Combine an array of disposables into a single disposable object
 * @param disposables The array of disposable objects
 */
export function combinedDisposable (disposables: IDisposable[]): IDisposable {
  return toDisposable(() => dispose(disposables));
}

/**
 * A Disposable object which does nothing
 */
export const EmptyDisposable = toDisposable(() => null);