You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: ulimit.go
    path of file: ./repos/kubernetes/vendor/github.com/docker/go-units
    
    the code of the file until where you have to start completion: package units

import (
	"fmt"
	"strconv"
	"strings"
)

// Ulimit is a human friendly version of Rlimit.
type Ulimit struct {
	Name string
	Hard int64
	Soft int64
}

// Rlimit specifies the resource limits, such as max open files.
type Rlimit struct {
	Type int    `json:"type,omitempty"`
	Hard 
    
func ParseUlimit(val string) (*Ulimit, error) {
	parts := strings.SplitN(val, "=", 2)
	if len(parts) != 2 {
		return nil, fmt.Errorf("invalid ulimit argument: %s", val)
	}

	if _, exists := ulimitNameMapping[parts[0]]; !exists {
		return nil, fmt.Errorf("invalid ulimit type: %s", parts[0])
	}

	var (
		soft int64
		hard = &soft // default to soft in case no hard was set
		temp int64
		err  error
	)
	switch limitVals := strings.Split(parts[1], ":"); len(limitVals) {
	case 2:
		temp, err = strconv.ParseInt(limitVals[1], 10, 64)
		if err != nil {
			return nil, err
		}
		hard = &temp
		fallthrough
	case 1:
		soft, err = strconv.ParseInt(limitVals[0], 10, 64)
		if err != nil {
			return nil, err
		}
	default:
		return nil, fmt.Errorf("too many limit value arguments - %s, can only have up to two, `soft[:hard]`", parts[1])
	}

	if *hard != -1 {
		if soft == -1 {
			return nil, fmt.Errorf("ulimit soft limit must be less than or equal to hard limit: soft: -1 (unlimited), hard: %d", *hard)
		}
		if soft > *hard {
			return nil, fmt.Errorf("ulimit soft limit must be less than or equal to hard limit: %d > %d", soft, *hard)
		}
	}

	return &Ulimit{Name: parts[0], Soft: soft, Hard: *hard}, nil
}