ronantakizawa/codereview-bench huggingface dataset:
Repository: sequelize/sequelize
File: packages/core/src/dialects/abstract/data-types.ts (TypeScript)

Code before:
import type { Falsy } from '@sequelize/utils';
import {
  EMPTY_ARRAY,
  isPlainObject,
  isString,
  parseBigInt,
  parseSafeInteger,
} from '@sequelize/utils';
import dayjs from 'dayjs';
import isEqual from 'lodash/isEqual';
import isObject from 'lodash/isObject';
import { Blob } from 'node:buffer';
import util from 'node:util';
import type { Class } from 'type-fest';
import { ValidationErrorItem } from '../../errors';
import type { GeoJson, GeoJsonType } from '../../geo-json.js';
import { assertIsGeoJson } from '../../geo-json.js';
import type { ModelStatic, Rangable, RangePart } from '../../model.js';
import type { Sequelize } from '../../sequelize.js';
import { makeBufferFromTypedArray } from '../../utils/buffer.js';
import { isValidTimeZone } from '../../utils/dayjs.js';
import { doNotUseRealDataType } from '../../utils/deprecations.js';
import { joinSQLFragments } from '../../utils/join-sql-fragments';
import { validator as Validator } from '../../utils/validator-extras';
import {
  attributeTypeToSql,

Review comment (suggestion):
Falsy is not a type that really makes sense to me. For instance, in this file, it should be replaced with `unknown`

Code after:
import {
  EMPTY_ARRAY,
  isPlainObject,
  isString,
  parseBigInt,
  parseSafeInteger,
} from '@sequelize/utils';
import dayjs from 'dayjs';
import isEqual from 'lodash/isEqual';
import isObject from 'lodash/isObject';
import { Blob } from 'node:buffer';
import util from 'node:util';
import type { Class } from 'type-fest';
import { ValidationErrorItem } from '../../errors';
import type { GeoJson, GeoJsonType } from '../../geo-json.js';
import { assertIsGeoJson } from '../../geo-json.js';
import type { ModelStatic, Rangable, RangePart } from '../../model.js';
import type { Sequelize } from '../../sequelize.js';
import { makeBufferFromTypedArray } from '../../utils/buffer.js';
import { isValidTimeZone } from '../../utils/dayjs.js';
import { doNotUseRealDataType } from '../../utils/deprecations.js';
import { joinSQLFragments } from '../../utils/join-sql-fragments';
import { validator as Validator } from '../../utils/validator-extras';
import {
  attributeTypeToSql,
  dataTypeClassOrInstanceToInstance,
Repository: sequelize/sequelize
File: packages/core/src/dialects/ibmi/data-types.ts (TypeScript)

Code before:
import type { Falsy } from '@sequelize/utils';
import * as BaseTypes from '../abstract/data-types.js';

export class UUID extends BaseTypes.UUID {
  toSql() {
    return 'CHAR(36)';
  }
}

export class BOOLEAN extends BaseTypes.BOOLEAN {
  escape(value: boolean | Falsy): string {
    return value ? '1' : '0';
  }

  toBindableValue(value: boolean | Falsy): unknown {
    return value ? 1 : 0;
  }

  toSql() {
    return 'SMALLINT';
  }
}

export {
  BIGINT,
  BLOB,

Review comment (suggestion):
same in this file. It's coercing any value not just boolean and falsy values

As a result, it can be removed from the utils package

Code after:
import * as BaseTypes from '../abstract/data-types.js';

export class UUID extends BaseTypes.UUID {
  toSql() {
    return 'CHAR(36)';
  }
}

export class BOOLEAN extends BaseTypes.BOOLEAN {
  escape(value: boolean | unknown): string {
    return value ? '1' : '0';
  }

  toBindableValue(value: boolean | unknown): unknown {
    return value ? 1 : 0;
  }

  toSql() {
    return 'SMALLINT';
  }
}

export {
  BIGINT,
  BLOB,
  CHAR,
Repository: sequelize/sequelize
File: packages/cli/src/commands/seed/generate.ts (TypeScript)

Code before:
import { config } from '../../_internal/config.js';
import { SequelizeCommand } from '../../_internal/sequelize-command.js';
import type { SupportedSeedFormat } from '../../api/generate-seed.js';
import { SUPPORTED_SEED_FORMATS, generateSeed } from '../../api/generate-seed.js';

export class GenerateSeed extends SequelizeCommand<(typeof GenerateSeed)['flags']> {
  static enableJsonFlag = true;

  static flags = {
    format: Flags.string({
      options: SUPPORTED_SEED_FORMATS,
      summary: 'The format of the seed file to generate',
      required: true,
    }),
    name: Flags.string({
      summary: 'A short name for the seed file',
      default: 'unnamed',
    }),
  };

  static summary = 'Generates a new seed file';

  static examples = [
    `<%= config.bin %> <%= command.id %>`,
    `<%= config.bin %> <%= command.id %> --format=sql`,
    `<%= config.bin %> <%= command.id %> --name="create users table"`,
  ];

  async run(): Promise<{ path: string }> {
    const { format, name: seedName } = this.flags;
    const { seedFolder } = config;

    const seedPath = await generateSeed({
      format: format as SupportedSeedFormat,
      seedName,
      seedFolder,
    });

    if (format === 'sql') {
      this.log(`SQL seed files generated in ${chalk.green(seedPath)}`);
    } else {
      this.log(`Seed file generated at ${chalk.green(seedPath)}`);
    }

    // JSON output
    return { path: seedPath };
  }
}


Review comment (suggestion):
```suggestion
    `<%= config.bin %> <%= command.id %> --name="users table test data"`,
```

Code after:
import { config } from '../../_internal/config.js';
import { SequelizeCommand } from '../../_internal/sequelize-command.js';
import type { SupportedSeedFormat } from '../../api/generate-seed.js';
import { SUPPORTED_SEED_FORMATS, generateSeed } from '../../api/generate-seed.js';

export class GenerateSeed extends SequelizeCommand<(typeof GenerateSeed)['flags']> {
  static enableJsonFlag = true;

  static flags = {
    format: Flags.string({
      options: SUPPORTED_SEED_FORMATS,
      summary: 'The format of the seed file to generate',
      required: true,
    }),
    name: Flags.string({
      summary: 'A short name for the seed file',
      default: 'unnamed',
    }),
  };

  static summary = 'Generates a new seed file';

  static examples = [
    `<%= config.bin %> <%= command.id %>`,
    `<%= config.bin %> <%= command.id %> --format=sql`,
    `<%= config.bin %> <%= command.id %> --name="users table test data"`,
  ];

  async run(): Promise<{ path: string }> {
    const { format, name: seedName } = this.flags;
    const { seedFolder } = config;

    const seedPath = await generateSeed({
      format: format as SupportedSeedFormat,
      seedName,
      seedFolder,
    });

    if (format === 'sql') {
      this.log(`SQL seed files generated in ${chalk.green(seedPath)}`);
    } else {
      this.log(`Seed file generated at ${chalk.green(seedPath)}`);
    }

    // JSON output
    return { path: seedPath };
  }
}
Repository: sequelize/sequelize
File: packages/core/src/sequelize-typescript.ts (TypeScript)

Code before:
import type { PartialBy } from '@sequelize/utils';
import {
  SortDirection,
  cloneDeepPlainValues,
  freezeDeep,
  inspect,
  isNullish,
  isString,
  join,
  localizedStringComparator,
  map,
  splitObject,
} from '@sequelize/utils';
import ansis from 'ansis';
import { AsyncLocalStorage } from 'node:async_hooks';
import semver from 'semver';
import type {
  Connection,
  CreateSchemaOptions,
  DataType,
  DataTypeClassOrInstance,
  DestroyOptions,
  ModelAttributes,
  ModelOptions,
  ModelStatic,
  QiListSchemasOptions,
  QueryOptions,
  RawConnectionOptions,
  SyncOptions,
  TruncateOptions,
} from '.';
import type {
  AbstractConnection,
  GetConnectionOptions,
} from './abstract-dialect/connection-manager.js';
import { normalizeDataType, validateDataType } from './abstract-dialect/data-types-utils.js';
import type { AbstractDataType } from './abstract-dialect/data-types.js';
import type { AbstractDialect, ConnectionOptions } from './abstract-dialect/dialect.js';
import type { EscapeOptions } from './abstract-dialect/query-generator-typescript.js';

Review comment (suggestion):
```suggestion
import { red, cyan } from 'ansis';
```
And related changes for this

Code after:
import type { PartialBy } from '@sequelize/utils';
import {
  SortDirection,
  cloneDeepPlainValues,
  freezeDeep,
  inspect,
  isNullish,
  isString,
  join,
  localizedStringComparator,
  map,
  splitObject,
} from '@sequelize/utils';
import { cyan, red } from 'ansis';
import { AsyncLocalStorage } from 'node:async_hooks';
import semver from 'semver';
import type {
  Connection,
  CreateSchemaOptions,
  DataType,
  DataTypeClassOrInstance,
  DestroyOptions,
  ModelAttributes,
  ModelOptions,
  ModelStatic,
  QiListSchemasOptions,
  QueryOptions,
  RawConnectionOptions,
  SyncOptions,
  TruncateOptions,
} from '.';
import type {
  AbstractConnection,
  GetConnectionOptions,
} from './abstract-dialect/connection-manager.js';
import { normalizeDataType, validateDataType } from './abstract-dialect/data-types-utils.js';
import type { AbstractDataType } from './abstract-dialect/data-types.js';
import type { AbstractDialect, ConnectionOptions } from './abstract-dialect/dialect.js';
import type { EscapeOptions } from './abstract-dialect/query-generator-typescript.js';
Repository: sequelize/sequelize
File: packages/utils/src/common/intersperse.ts (TypeScript)

Code before:
import { isFunction } from './predicates/is-function.js';

/**
 * Inserts a value between each element of a list.
 * `separator` can be a function, which is useful to generate JSX elements with different keys.
 *
 * @param list The list
 * @param separator The value to insert between each element of the list, or a function that will produce each element to insert.
 */
export function intersperse<Val, Sep>(
  list: Val[],
  separator: Sep | ((index: number) => Sep),
): Array<Val | Sep> {
  const res: Array<Val | Sep> = [];

  if (list.length === 0) {
    return res;
  }

  const separatorIsFunction = isFunction(separator);

  let i = 0;

  res.push(list[i++]);
  while (i < list.length) {
    res.push(separatorIsFunction ? separator(i) : separator, list[i++]);
  }

  return res;
}


Review comment (suggestion):
```suggestion
export function intersperse<Value, Separator>(
  list: Value[],
  separator: Separator | ((index: number) => Separator),
): Array<Value | Separator> {
  const res: Array<Value | Separator> = [];
```

Code after:
import { isFunction } from './predicates/is-function.js';

/**
 * Inserts a value between each element of a list.
 * `separator` can be a function, which is useful to generate JSX elements with different keys.
 *
 * @param list The list
 * @param separator The value to insert between each element of the list, or a function that will produce each element to insert.
 */
export function intersperse<Value, Separator>(
  list: Value[],
  separator: Separator | ((index: number) => Separator),
): Array<Value | Separator> {
  const res: Array<Value | Separator> = [];

  if (list.length === 0) {
    return res;
  }

  const separatorIsFunction = isFunction(separator);

  let i = 0;

  res.push(list[i++]);
  while (i < list.length) {
    res.push(separatorIsFunction ? separator(i) : separator, list[i++]);
  }

  return res;
}
Repository: sequelize/sequelize
File: packages/core/test/types/model-count.ts (TypeScript)

Code before:
import { Model, Op } from '@sequelize/core';
import { expectTypeOf } from 'expect-type';

class MyModel extends Model {}

expectTypeOf(MyModel.count()).toEqualTypeOf<Promise<number>>();
expectTypeOf(MyModel.count({ group: 'tag', countGroupedRows: true })).toEqualTypeOf<
  Promise<Array<{ [key: string]: unknown; count: number }>>
>();
expectTypeOf(MyModel.count({ col: 'tag', distinct: true })).toEqualTypeOf<Promise<number>>();
expectTypeOf(
  MyModel.count({
    where: {
      updatedAt: {
        [Op.gte]: new Date(),
      },
    },
    useMaster: false,
  }),
).toEqualTypeOf<Promise<number>>();


Review comment (suggestion):
```suggestion
expectTypeOf(MyModel.count({ group: 'tag' })).toEqualTypeOf<
  Promise<Array<{ [key: string]: unknown; count: number }>>
>();
expectTypeOf(MyModel.count({ group: 'tag', countGroupedRows: true })).toEqualTypeOf<
  Promise<Array<{ [key: string]: unknown; count: number }>>
>();
```
The old one is still valid

Code after:
import { Model, Op } from '@sequelize/core';
import { expectTypeOf } from 'expect-type';

class MyModel extends Model {}

expectTypeOf(MyModel.count()).toEqualTypeOf<Promise<number>>();
expectTypeOf(MyModel.count({ group: 'tag' })).toEqualTypeOf<
  Promise<Array<{ [key: string]: unknown; count: number }>>
>();
expectTypeOf(MyModel.count({ group: 'tag', countGroupedRows: true })).toEqualTypeOf<
  Promise<Array<{ [key: string]: unknown; count: number }>>
>();
expectTypeOf(MyModel.count({ col: 'tag', distinct: true })).toEqualTypeOf<Promise<number>>();
expectTypeOf(
  MyModel.count({
    where: {
      updatedAt: {
        [Op.gte]: new Date(),
      },
    },
    useMaster: false,
  }),
).toEqualTypeOf<Promise<number>>();
Repository: serde-rs/serde
File: src/bytes.rs (Rust)

Code before:
        where S: ser::Serializer
    {
        serializer.visit_bytes(self.bytes)
    }
}

///////////////////////////////////////////////////////////////////////////////

/// `ByteBuf` wraps a `Vec<u8>` in order to hook into serialize and from deserialize a byte array.
#[derive(Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct ByteBuf {
    bytes: Vec<u8>,
}

impl ByteBuf {
    pub fn new() -> Self {
        ByteBuf {
            bytes: Vec::new(),
        }
    }

    pub fn with_capacity(cap: usize) -> Self {
        ByteBuf {
            bytes: Vec::with_capacity(cap)
        }
    }

    pub fn as_vec(self) -> Vec<u8> {
        self.bytes
    }
}

impl fmt::Debug for ByteBuf {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "b\"{}\"", escape_bytestring(self.bytes.as_ref()))
    }
}

impl<T> From<T> for ByteBuf where T: Into<Vec<u8>> {
    fn from(bytes: T) -> Self {
        ByteBuf {
            bytes: bytes.into(),
        }
    }
}

impl AsRef<Vec<u8>> for ByteBuf {
    fn as_ref(&self) -> &Vec<u8> {
        &self.bytes
    }
}

Review comment (suggestion):
Would conflict with `From<T>` at line 94:

``` rust
impl Into<Vec<u8>> for ByteBuf {...}
impl<T> From<T> for ByteBuf where T: Into<Vec<u8>> {...}
```

```
src/bytes.rs:100:1: 106:2 error: conflicting implementations for trait `core::convert::From` [E0119]
src/bytes.rs:100 impl<T> From<T> for ByteBuf where T: Into<Vec<u8>> {
src/bytes.rs:101     fn from(bytes: T) -> Self {
src/bytes.rs:102         ByteBuf {
src/bytes.rs:103             bytes: bytes.into(),
src/bytes.rs:104         }
src/bytes.rs:105     }
                 ...
src/bytes.rs:100:1: 106:2 note: conflicting implementation in crate `core`
src/bytes.rs:100 impl<T> From<T> for ByteBuf where T: Into<Vec<u8>> {
src/bytes.rs:101     fn from(bytes: T) -> Self {
src/bytes.rs:102         ByteBuf {
src/bytes.rs:103             bytes: bytes.into(),
src/bytes.rs:104         }
src/bytes.rs:105     }
                 ...
```


Code after:
    {
        serializer.visit_bytes(self.bytes)
    }
}

///////////////////////////////////////////////////////////////////////////////

/// `ByteBuf` wraps a `Vec<u8>` in order to hook into serialize and from deserialize a byte array.
#[derive(Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct ByteBuf {
    bytes: Vec<u8>,
}

impl ByteBuf {
    pub fn new() -> Self {
        ByteBuf {
            bytes: Vec::new(),
        }
    }

    pub fn with_capacity(cap: usize) -> Self {
        ByteBuf {
            bytes: Vec::with_capacity(cap)
        }
    }
}

impl fmt::Debug for ByteBuf {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "b\"{}\"", escape_bytestring(self.bytes.as_ref()))
    }
}

impl Into<Vec<u8>> for ByteBuf {
    fn into(self) -> Vec<u8> {
        self.bytes
    }
}

impl From<Vec<u8>> for ByteBuf {
    fn from(bytes: Vec<u8>) -> Self {
        ByteBuf {
            bytes: bytes,
        }
    }
}

impl AsRef<Vec<u8>> for ByteBuf {
    fn as_ref(&self) -> &Vec<u8> {
        &self.bytes
    }
Repository: serde-rs/serde
File: src/bytes.rs (Rust)

Code before:
        where S: ser::Serializer
    {
        serializer.visit_bytes(self.bytes)
    }
}

///////////////////////////////////////////////////////////////////////////////

/// `ByteBuf` wraps a `Vec<u8>` in order to hook into serialize and from deserialize a byte array.
#[derive(Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct ByteBuf {
    bytes: Vec<u8>,
}

impl ByteBuf {
    pub fn new() -> Self {
        ByteBuf {
            bytes: Vec::new(),
        }
    }

    pub fn with_capacity(cap: usize) -> Self {
        ByteBuf {
            bytes: Vec::with_capacity(cap)
        }
    }

    pub fn as_vec(self) -> Vec<u8> {
        self.bytes
    }
}

impl fmt::Debug for ByteBuf {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "b\"{}\"", escape_bytestring(self.bytes.as_ref()))
    }
}

impl<T> From<T> for ByteBuf where T: Into<Vec<u8>> {
    fn from(bytes: T) -> Self {
        ByteBuf {
            bytes: bytes.into(),
        }
    }
}

impl AsRef<Vec<u8>> for ByteBuf {
    fn as_ref(&self) -> &Vec<u8> {
        &self.bytes
    }
}

Review comment (suggestion):
I would suggest removing 

``` rust
impl<T> From<T> for ByteBuf where T: Into<Vec<u8>>
```

in favor of simpler

``` rust
impl From<Vec<u8>> for ByteBuf
```

Though that would be a breaking change.


Code after:
    {
        serializer.visit_bytes(self.bytes)
    }
}

///////////////////////////////////////////////////////////////////////////////

/// `ByteBuf` wraps a `Vec<u8>` in order to hook into serialize and from deserialize a byte array.
#[derive(Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct ByteBuf {
    bytes: Vec<u8>,
}

impl ByteBuf {
    pub fn new() -> Self {
        ByteBuf {
            bytes: Vec::new(),
        }
    }

    pub fn with_capacity(cap: usize) -> Self {
        ByteBuf {
            bytes: Vec::with_capacity(cap)
        }
    }
}

impl fmt::Debug for ByteBuf {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "b\"{}\"", escape_bytestring(self.bytes.as_ref()))
    }
}

impl Into<Vec<u8>> for ByteBuf {
    fn into(self) -> Vec<u8> {
        self.bytes
    }
}

impl From<Vec<u8>> for ByteBuf {
    fn from(bytes: Vec<u8>) -> Self {
        ByteBuf {
            bytes: bytes,
        }
    }
}

impl AsRef<Vec<u8>> for ByteBuf {
    fn as_ref(&self) -> &Vec<u8> {
        &self.bytes
    }
Repository: serde-rs/serde
File: src/bytes.rs (Rust)

Code before:
        where S: ser::Serializer
    {
        serializer.visit_bytes(self.bytes)
    }
}

///////////////////////////////////////////////////////////////////////////////

/// `ByteBuf` wraps a `Vec<u8>` in order to hook into serialize and from deserialize a byte array.
#[derive(Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct ByteBuf {
    bytes: Vec<u8>,
}

impl ByteBuf {
    pub fn new() -> Self {
        ByteBuf {
            bytes: Vec::new(),
        }
    }

    pub fn with_capacity(cap: usize) -> Self {
        ByteBuf {
            bytes: Vec::with_capacity(cap)
        }
    }

    pub fn as_vec(self) -> Vec<u8> {
        self.bytes
    }
}

impl fmt::Debug for ByteBuf {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "b\"{}\"", escape_bytestring(self.bytes.as_ref()))
    }
}

impl<T> From<T> for ByteBuf where T: Into<Vec<u8>> {
    fn from(bytes: T) -> Self {
        ByteBuf {
            bytes: bytes.into(),
        }
    }
}

impl AsRef<Vec<u8>> for ByteBuf {
    fn as_ref(&self) -> &Vec<u8> {
        &self.bytes
    }
}

Review comment (suggestion):
does removing the `From` impl and adding the `Into` impl work?
Then the `From` impl is generated in the standard library if I read this correctly.


Code after:
    {
        serializer.visit_bytes(self.bytes)
    }
}

///////////////////////////////////////////////////////////////////////////////

/// `ByteBuf` wraps a `Vec<u8>` in order to hook into serialize and from deserialize a byte array.
#[derive(Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct ByteBuf {
    bytes: Vec<u8>,
}

impl ByteBuf {
    pub fn new() -> Self {
        ByteBuf {
            bytes: Vec::new(),
        }
    }

    pub fn with_capacity(cap: usize) -> Self {
        ByteBuf {
            bytes: Vec::with_capacity(cap)
        }
    }
}

impl fmt::Debug for ByteBuf {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "b\"{}\"", escape_bytestring(self.bytes.as_ref()))
    }
}

impl Into<Vec<u8>> for ByteBuf {
    fn into(self) -> Vec<u8> {
        self.bytes
    }
}

impl From<Vec<u8>> for ByteBuf {
    fn from(bytes: Vec<u8>) -> Self {
        ByteBuf {
            bytes: bytes,
        }
    }
}

impl AsRef<Vec<u8>> for ByteBuf {
    fn as_ref(&self) -> &Vec<u8> {
        &self.bytes
    }
Repository: serde-rs/serde
File: src/bytes.rs (Rust)

Code before:
        where S: ser::Serializer
    {
        serializer.visit_bytes(self.bytes)
    }
}

///////////////////////////////////////////////////////////////////////////////

/// `ByteBuf` wraps a `Vec<u8>` in order to hook into serialize and from deserialize a byte array.
#[derive(Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct ByteBuf {
    bytes: Vec<u8>,
}

impl ByteBuf {
    pub fn new() -> Self {
        ByteBuf {
            bytes: Vec::new(),
        }
    }

    pub fn with_capacity(cap: usize) -> Self {
        ByteBuf {
            bytes: Vec::with_capacity(cap)
        }
    }

    pub fn as_vec(self) -> Vec<u8> {
        self.bytes
    }
}

impl fmt::Debug for ByteBuf {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "b\"{}\"", escape_bytestring(self.bytes.as_ref()))
    }
}

impl<T> From<T> for ByteBuf where T: Into<Vec<u8>> {
    fn from(bytes: T) -> Self {
        ByteBuf {
            bytes: bytes.into(),
        }
    }
}

impl AsRef<Vec<u8>> for ByteBuf {
    fn as_ref(&self) -> &Vec<u8> {
        &self.bytes
    }
}

Review comment (suggestion):
> Then the From impl is generated in the standard library if I read this correctly.

Yes, the offending implementation is 

``` rust
impl<T> From<T> for T
```

http://doc.rust-lang.org/src/core/convert.rs.html#152


Code after:
    {
        serializer.visit_bytes(self.bytes)
    }
}

///////////////////////////////////////////////////////////////////////////////

/// `ByteBuf` wraps a `Vec<u8>` in order to hook into serialize and from deserialize a byte array.
#[derive(Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct ByteBuf {
    bytes: Vec<u8>,
}

impl ByteBuf {
    pub fn new() -> Self {
        ByteBuf {
            bytes: Vec::new(),
        }
    }

    pub fn with_capacity(cap: usize) -> Self {
        ByteBuf {
            bytes: Vec::with_capacity(cap)
        }
    }
}

impl fmt::Debug for ByteBuf {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "b\"{}\"", escape_bytestring(self.bytes.as_ref()))
    }
}

impl Into<Vec<u8>> for ByteBuf {
    fn into(self) -> Vec<u8> {
        self.bytes
    }
}

impl From<Vec<u8>> for ByteBuf {
    fn from(bytes: Vec<u8>) -> Self {
        ByteBuf {
            bytes: bytes,
        }
    }
}

impl AsRef<Vec<u8>> for ByteBuf {
    fn as_ref(&self) -> &Vec<u8> {
        &self.bytes
    }